#C++基础# 内存分配函数:malloc,calloc,realloc,_alloca, new, free, delete

malloc:

void *malloc(size_t size);
  • 功能:在堆区申请空间长度为size字节连续的内存块。
  • 参数:size--申请空间长度字节大小
  • 返回值:如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定)即申请空间的首地址,否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。
  • 注意:void* 表示未确定类型的指针,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者...)
  • 工作机制:malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。如果无法获得符合要求的内存块,malloc函数会返回NULL指针,因此在调用malloc动态申请内存块时,一定要进行返回值的判断。

calloc

void *calloc(unsigned n,unsigned size);
  • 功能:在堆区申请连续的 num 块内存,每块内存的字节数为size;并将这些字节置为初始化为0,返回值为所申请空间的首地址,申请数组时比较方便,但是效率可能比malloc()会慢一点,因为多了一步初始化操作
  • 参数:n--连续的块内存数,size--每块内存的字节数
  • 返回值:如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定)即申请空间的首地址,否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。
  • 注意:void* 表示未确定类型的指针,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者...)

realloc

void* realloc(void* memblock, size_t size);
  • 功能:先判断当前的指针是否有足够的连续空间,如果有,扩大memblock指向的地址,并且将memblock返回,如果空间不够,先按照size指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来memblock所指内存区域,同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。
  • 参数:membloc--当前的内存块指针, size--扩大指定
  • 返回值:如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定)即申请空间的首地址,否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。
  • 注意:void* 表示未确定类型的指针,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者...)

 _alloca:

void * __cdecl alloca(size_t);

内存分配函数,与malloc,calloc,realloc类似,但是注意一个重要的区别,_alloca是在栈(stack)上申请空间,用完马上就释放.

在调用 alloca() 的函数返回的时候, 它分配的内存会自动释放。也就是说, 用 alloca 分配的内存在某种程度上局部于函数的 ``堆栈帧"  或上下文中。alloca() 不具可移植性, 而且在没有传统堆栈的机器上很难实现。 当它的返回值直接传入另一个函数时会带来问题。

 fgets(alloca(100), 100, stdin)

由于这些原因, alloca() 不合标准, 不宜使用在必须广泛移植的程序中, 不管它可能多么有用。 既然 C99 支持变长数组(VLA), 它可以用来更好的 完成 alloca() 以前的任务。不提倡使用

new/new[]

  • 功能:在堆区申请空间长度为当前类型(当前类型*数组)字节连续的内存块。
  • 参数:void
  • 返回值:如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定)即申请空间的首地址,否则返回空指针NULL。当内存不再使用时,应使用delete delete[]函数将内存块释放。
  • 注意:new对象时候会自动调用构造函数。

free

void free(void *ptr)
  • 功能:释放内存块。
  • 参数:ptr--指针指向一个要释放内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。如果传递的参数是一个空指针,则不会执行任何动作。
  • 返回值:void
  • 注意:free()不能去释放栈区的空间,栈区空间是由OS管理的,由OS进行申请和释放。释放空间后,指针需要置空,避免成为野指针

delete/delete[]

  • 功能:释放内存块。
  • 返回值:void
  • 注意:因使用delete对象时候会自动调用析构函数,对象数组空间必须使用delete[]进行释放,基本类型数组空间可以delete/delete[]进行释放。delete不能去释放栈区的空间,栈区空间是由OS管理的,由OS进行申请和释放。释放空间后,指针需要置空,避免成为野指针
发布了170 篇原创文章 · 获赞 207 · 访问量 459万+

猜你喜欢

转载自blog.csdn.net/xiaoting451292510/article/details/105094625