void *malloc ( size_t size );
malloc申请的是一块连续的内存。有时会申请不到内存,返回NULL。
size是请求分配的内存字节数,成功则返回一个指向内存的指针,否则返回NULL。
malloc实际分配的内存空间可能会比你请求的多一点,但是这个行为只是由编译器定义的。
malloc不知道用户所请求的内存需要存储的数据类型,所以malloc返回一个void *的指针,它可以转换为其它任何类型的指针。
注意: malloc出的内存不是清0,需要自己memset。
void free ( void *pointer );
free的参数必须要么是NULL,要么是从malloc、relloc、calloc返回的值。作用是释放之前返回的指针指向的内存空间,向free传递一个NULL参数不会产生任何效果。
free使用习惯
free(p);
p = NULL;
注意:
不允许重复释放
给free函数传递其它的值很可能造成死机或其它灾难性的后果。
void *calloc ( size_t num_elements, size_t element_size );
void *realloc (void *ptr, size_t new_size );
calloc和malloc 主要的区别在于前者在返回内存的指针之前将它初始化为0
calloc的参数包括所需元素的数量和每个元素的字节
realloc函数用于修改一个原先已经分配的内存块的大小,可以使一块内存的扩大或缩小。
当起始空间的地址为空,即ptr = NULL,则同malloc。
当ptr非空:若nuw_size < size,即缩小ptr所指向的内存空间,该内存块尾部的部分内存被拿掉,剩余部分内存的原先内容依然保留;若nuw_size > size,即扩大ptr所指向的内存空间,如果原先的内存尾部有足够的扩大空间,则直接在原先的内存块尾部新增内存,如果原先的内存尾部空间不足,或原先的内存块无法改变大小,realloc将重新分配另一块nuw_size大小的内存,并把原先那块内存的内容复制到新的内存块上。因此,使用realloc后就应该改用realloc返回的新指针。
●避免分配大量的小内存块。分配堆上的内存有一些系统开销,所以分配许多小的内存块比分配几个大内存块的系统开销大。
●仅在需要时分配内存。只要使用完堆上的内存块,就释放它。
●总是确保释放已分配的内存。在编写分配内存的代码时,就要确定在代码的什么地方释放内存。
●在释放内存之前,确保不会无意中覆盖堆上分配的内存的地址,否则程序就会出现内存泄漏。在循环中分配内存时,要特别小心。
void *alloca(size_t size);
功能:size是请求分配的内存大小(字节),alloca函数和前面的函数都不同,前面的函数在进程的堆空间中分配内存,所以需要手动free,
而alloca函数在进程的栈空间中分配内存,所以当调用alloca函数的函数执行结束时,alloca分配的内存也就自动释放。
注意:我在vc6.0上使用这个函数时,提示函数未定义!
从原型上看,malloc的含义是“给我一个大小为size的连续内存”,而calloc貌似是“给我n个大小为size的内存”。
有人说calloc返回的对象数组而malloc仅仅是一块连续的内存。
这让我产生了非常大的迷惑。为什么返回值仅仅有一个?难道返回的是数组的首地址,数组里面存的是分配的n块内存的地址?
难道calloc的n个大小为size的连续内存,还是在这n个之间可能还是不连续的?如果是这样对这块内存怎么释放呢?
“n个大小为size的内存”这句话本身就有歧义(是“一块内存大小是n个size”呢?还是“n块内存每块大小为size”)。
带着这些疑问我看了看用calloc申请的内存是怎样用free来释放的,结果是跟malloc一样仅仅free一次就够了。
这个网址(http://www.cnblogs.com/ecizep/p/4417573.html)上有这么一段描写叙述:
“malloc在分配内存的时候会保留一定的空间用来记录分配情况,分配的次数越多,这些记录占用的空间就越多。
另外,依据malloc实现策略的不同,malloc每次在分配的时候,可能分配的空间比实际要求的多些。
多次分配会导致很多其它的这样的浪费,当然,这些都跟malloc的实现有关”。
记录内存的使用情况是非常正常的啊,要不内存怎么用free来释放呢?可是这里强调malloc的这一点却没有说calloc,难道calloc不用记录?那么free是怎样释放用它申请的空间的?calloc究竟是个什么?太奇妙了,我该看看calloc的源代码。
从以下这个网址我找到了一段calloc的源代码(apple的地址至少还稍具权威性),尽管实现方式有多种,但这段代码就足以可以说明calloc是什么了:
http://www.opensource.apple.com/source/gcc/gcc-5575.11/libiberty/calloc.c#include "ansidecl.h"
#include /* For systems with larger pointers than ints, this must be declared. */
PTR malloc (size_t);
void bzero (PTR, size_t);PTR
calloc (size_t nelem, size_t elsize)
{register PTR ptr; if (nelem == 0 || elsize == 0)nelem = elsize = 1;ptr = malloc (nelem * elsize);if (ptr) bzero (ptr, nelem * elsize);return ptr;
}
看了这段代码, 发现 calloc就是通过malloc实现的, 然后对其进行的清理。 calloc就是个鸡肋~~~
1、malloc分配的内存是连续的。
2、堆中的内存不一定是连续的。而是一块一块以链表的形式存在的。而链表中的每一个节点(即一块)都是连续的。
3、分配算法是,找到合适大小的一块,分配给用户,如果没有,则把大块的切正两小块。用户释放后,需要进行小块内存的合并。