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

  1. 调用malloc请求并分配内存。
  2. 调用结构函数, 初始化相应类型的目标,并回来首地址。
  • new运算符会抛出std::bad_alloc反常,假如参加nothrow,则不抛出反常,而是回来nullptr。

delete

  1. 调用析构函数
  2. 开释内存(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
  • 目标毁掉后拜访无主引证,会产生运行时错误(野指针)。