4. 分配内存的函数
除了malloc
之外,C标准库还提供了另外两个在堆空间分配内存的函数,它们分配的内存同样由free
释放。
- #include <stdlib.h>
- void *calloc(size_t nmemb, size_t size);
- void *realloc(void *ptr, size_t size);
- 返回值:成功返回所分配内存空间的首地址,出错返回NULL
calloc
的参数很像fread
/fwrite
的参数,分配nmemb
个元素的内存空间,每个元素占size
字节,并且calloc
负责把这块内存空间用字节0填充,而malloc
并不负责把分配的内存空间清零。
有时候用malloc
或calloc
分配的内存空间使用了一段时间之后需要改变它的大小,一种办法是调用malloc
分配一块新的内存空间,把原内存空间中的数据拷到新的内存空间,然后调用free
释放原内存空间。使用realloc
函数简化了这些步骤,把原内存空间的指针ptr
传给realloc
,通过参数size
指定新的大小(字节数),realloc
返回新内存空间的首地址,并释放原内存空间。新内存空间中的数据尽量和原来保持一致,如果size
比原来小,则前size
个字节不变,后面的数据被截断,如果size
比原来大,则原来的数据全部保留,后面长出来的一块内存空间未初始化(realloc
不负责清零)。注意,参数ptr
要么是NULL
,要么必须是先前调用malloc
、calloc
或realloc
返回的指针,不能把任意指针传给realloc
要求重新分配内存空间。作为两个特例,如果调用realloc(NULL, size)
,则相当于调用malloc(size)
,如果调用realloc(ptr, 0)
,ptr
不是NULL
,则相当于调用free(ptr)
。
- #include <alloca.h>
- void *alloca(size_t size);
- 返回值:返回所分配内存空间的首地址,如果size太大导致栈空间耗尽,结果是未定义的
参数size
是请求分配的字节数,alloca
函数不是在堆上分配空间,而是在调用者函数的栈帧上分配空间,类似于C99的变长数组,当调用者函数返回时自动释放栈帧,所以不需要free
。这个函数不属于C标准库,而是在POSIX标准中定义的。