alloc()malloc()calloc()realloc()区别及用法

Posted shuang0109

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了alloc()malloc()calloc()realloc()区别及用法相关的知识,希望对你有一定的参考价值。

C语言跟内存申请相关的函数主要有 alloca,calloc,malloc,free,realloc,sbrk等.

       函数malloc()和calloc()都可以用来动态分配内存空间,但两者稍有区别。 
  malloc()函数有一个参数,即要分配的内存空间的大小:     

  void *malloc(size_t size); 

  calloc()函数有两个参数,分别为元素的数目和每个元素的大小,这两个参数的乘积就是要分配的内存空间的大小。 

  void *calloc(size_t numElements, size_t sizeOfElement); 

  如果调用成功,函数malloc()和函数calloc()都将返回所分配的内存空间的首地址。

  函数malloc()和函数calloc()的主要区别是前者不能初始化所分配的内存空间,而后者能。如果由malloc()函数分配的内存空间原来没有 被使用过,则其中的每一位可能都是0;反之,如果这部分内存曾经被分配过,则其中可能遗留有各种各样的数据。也就是说,使用malloc()函数的程序开 始时(内存空间还没有被重新分配)能正常进行,但经过一段时间(内存空间还已经被重新分配)可能会出现问题。 需要调用函数memset来初始化这部分的内存空间.

  malloc()函数的工作机制

  malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。


  函数calloc()会将所分配的内存空间中的每一位都初始化为零,也就是说,如果你是为字符类型或整数类型的元素分配内存,那麽这些元素将保证会被初始 化为0;如果你是为指针类型的元素分配内存,那麽这些元素通常会被初始化为空指针;如果你为实型数据分配内存,则这些元素会被初始化为浮点型的零。

  alloca是向栈申请内存,因此无需释放. alloc与afree以栈的方式(即后进先出的列表)进行存储空间的管理。

  realloc(void *__ptr, size_t __size):更改已经配置的内存空间,即更改由malloc()函数分配的内存空间的大小。

  如果将分配的内存减少,realloc仅仅是改变索引的信息。

  如果是将分配的内存扩大,则有以下情况:
  1)如果当前内存段后面有需要的内存空间,则直接扩展这段内存空间,realloc()将返回原指针。
  2)如果当前内存段后面的空闲字节不够,那么就使用堆中的第一个能够满足这一要求的内存块,将目前的数据复制到新的位置,并将原来的数据块释放掉,返回新的内存块位置。
  3)如果申请失败,将返回NULL,此时,原来的指针仍然有效。

  注意:如果调用成功,不管当前内存段后面的空闲空间是否满足要求,都会释放掉原来的指针,重新返回一个指针,虽然返回的指针有可能和原来的指针一样,即不能再次释放掉原来的指针。

以上是关于alloc()malloc()calloc()realloc()区别及用法的主要内容,如果未能解决你的问题,请参考以下文章

Why malloc+memset is slower than calloc?

iOS之深入解析malloc的底层原理

C ++中的“new”和“malloc”和“calloc”有啥区别? [复制]

malloc,calloc,realloc解析

动态开内存malloc与calloc

realloc,malloc,calloc函数的区别