c内存办理
Malloc
void* malloc(size_t size)
- 在堆中分配一个长度为size字节的接连空间,回来一个指向所分配的接连存储域的开始地址的指针
void*
(能够转换为任何其它类型的指针)。 - 分配的内存未初始化,它们的值是不知道的。
- 当函数未能成功分配存储空间时(如内存不足)则回来一个
NULL
指针。
uint16_t *p = (uin16_t *)malloc(sizeof(uint16_t));
if (NULL == p)
{
printf("malloc error\r\n");
} else
{
memset(p, 0, n * sizeof(uint16_t)); // 内存的值不知道, 需求初始化为0
}
calloc
void *calloc(int num, int size)
- 分配 num 个长度为 size 的接连空间,并将每一个字节都
初始化为 0
realloc
void *realloc(void *address, int newsize);
-
重新分配内存
,把内存扩展到 newsize。 - 从堆上当前内存段后边的字节中获得更多的内存空间,假如能够满意,则回来原指针;
- 假如后边的闲暇字节不行,那么就运用堆上第一个能够满意这一要求的内存块,将现在的数据复制到新的方位,而将原来的数据块开释掉。
- 假如内存不足,重新请求空间失利,则回来NULL。
- 此刻原来指针依然有效,
memcpy
memcpy(void *dst, void *src, size_t n)
- 从源内存区域复制数据到目标内存区域。
memmove
memcpy(void *dst, void *src, size_t n)
功能和 memcpy 类似, 但它能够处理dst和src重叠的内存区域
。
free
void free(void *address);
- 调用free开释内存后,不能再拜访被开释的内存空间, 此刻的指针变成
悬空指针
, 所以最好手动赋值NULL
-
不能两次开释相同的指针
。由于开释内存空间后,该空间就交给了内存分配子程序,再次开释内存空间会导致错误。 - 有必要供给内存的
开始地址
,不能够供给部分地址
,开释内存中的一部分是不允许的。 - malloc和free成对运用, 防止
内存走漏
C++内存办理
new
- 调用
malloc
请求并分配内存。 - 调用
结构函数
, 初始化相应类型的目标,并回来首地址。
- new运算符会抛出
std::bad_alloc
反常,假如参加nothrow
,则不抛出反常,而是回来nullptr。
delete
- 调用
析构函数
- 开释内存(
free
)
new[]/delete[]
初始化或许开释目标数组
依照目标的个数,分别调用结构函数和析构函数
unique_ptr
- 具有目标独有所有权语义的智能指针
- unique_ptr 不同享它的指针。它无法复制到其他 unique_ptr,只能
移动
unique_ptr。 - 移动后, 内存资源所有权将搬运到另一unique_ptr,而且原始 unique_ptr 不再具有此资源。
unique_ptr<int> pInt(new int(8));
unique_ptr<int> pInt2 = std::move(pInt); // 搬运所有权
//cout << *pInt << endl; // 出错,pInt为空
cout << *pInt2 << endl;
shared_ptr
- 具有同享目标所有权语义的智能指针
- 记录目标被引证的次数,当引证次数为 0 的时分,也便是最终一个指向该目标的同享指针析构的时分,同享指针的析构函数就把指向的内存区域开释掉。
- 它所指向的资源具有同享性,即多个shared_ptr能够指向同一份资源,并在内部运用引证计数机制来实现这一点。
weak_ptr
办理目标的弱引证
OC内存办理
引证计数
-
alloc/retain/copy
引证计数+1 -
release
引证计数 -1 -
autorelease
出了autoreleasepool(主动开释池))后, 引证计数再 -1 - 但凡运用了alloc、retain或许copy让内存的引⽤用计数增加了,就需求运用release或许autorelease让内存的引证计数削减。需求
一一对应
。 - 当引证计数降为0之后,不应该再运用这块内存空间;
dealloc
当引证计数减到0的时分,系统自发调用dealloc办法开释内存。
ARC
- 主动引证计数,
编译器
帮我们办理目标的retainCount值 - 当开启ARC后, 上述手动改动引证计数的办法就无法运用了
- ARC是
编译器特性
,编译器在编译的时分,会在合适的方位,主动插入内存办理的代码
Swift内存办理
Swift无法运用MRC,只支撑ARC
strong
默许界说的目标满是强引证,引证计数+1
weak
- 界说弱引证, 不会改动目标的引证计数
- 弱引证变量有必要是可选类型的
var
,由于目标毁掉后,ARC会主动将弱引证设置为nil
。
weak var p: Person? = Person()
unowned
- 界说无主引证, 不会改动目标的引证计数
- 目标毁掉后依然存储着实例的内存地址,不会主动设置
nil
- 目标毁掉后拜访无主引证,会产生运行时错误(野指针)。