malloc, free, calloc, realloc - allocate and free dynamic memory
malloc,free,calloc,realloc-动态分配和释放内存
所需头文件
#include <stdlib.h>
void *malloc(size_t size);
void free(void *ptr);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
The malloc() function allocates size bytes and returns a pointer to the allocated memory. The memory is not initialized. If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().
malloc函数分配size byte的内存,并且返回一个指向这块内存的指针,这块内存没有初始化,如果size的大小是0,malloc会返回NULL,或者能传递给free()的一个独特的指针值
The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed.
free()函数通过ptr释放所对应的内存空间,这些内存指针必须是通过malloc,calloc或者relloc返回的,否则,如果之前有调用free方法去释放ptr所对应的指针,那么会发生未定义的行为,如果ptr已经是NULL,那么就什么都不做
The calloc() function allocates memory for an array of nmemb elements of size bytes each and returns a pointer to the allocated memory. The memory is set to zero. If nmemb or size is 0, then calloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().
calloc()函数分配size大小的一系列的nmemb元素,返回指向分配的内存,如果nmemb或者size是0,calloc()返回NULL或者一个能传递给free()的独特的指针值
The realloc() function changes the size of the memory block pointed to by ptr to size bytes. The contents will be unchanged in the range from the start of the region up to the minimum of the old and new sizes. If the new size is larger than the old size, the added memory will not be initialized. If ptr is NULL, then the call is equivalent to malloc(size), for all values of size; if size is equal to zero, and ptr is not NULL, then the call is equivalent to free(ptr). Unless ptr is NULL, it must have been returned by an earlier call to malloc(), calloc() or realloc(). If the area pointed to was moved, a free(ptr) is done.
realloc函数改变通过ptr改变ptr所指向内存块的大小到size byte,ptr原先所指向的内存块里面的内容不会被改变,如果新的size比以前大,那么增加的memory将不会被初始化,如果ptr是NULL,那么等同于malloc(size),不管size的值是多少,如果size是0,ptr不是NULL,那么相当于free(ptr)。如果ptr不是NULL,那么ptr一定是之前malloc,calloc,realloc的返回值,如果所指向的区域被移动了(这个可能是当前区域无法容纳所需要的内存),那么会调用一个free(ptr)来释放以前所占用的区域。
返回值
The malloc() and calloc() functions return a pointer to the allocated memory that is suitably aligned for any kind of variable. On error, these functions return NULL. NULL may also be returned by a successful call to malloc() with a size of zero, or by a successful call to calloc() with nmemb or size equal to zero.
malloc和calloc函数返回一个指针,对任何类型的变量都是对齐的,大小合适的,错误的时候这些函数返回NULL,NULL也可能是0作为malloc参数成功的返回值,或者,nmemb或size为0作为参数成功的返回值
The free() function returns no value.
free函数没有返回值
The realloc() function returns a pointer to the newly allocated memory, which is suitably aligned for any kind of variable and may be different from ptr, or NULL if the request fails. If size was equal to 0, either NULL or a pointer suitable to be passed to free() is returned. If realloc() fails the original block is left untouched; it is not freed or moved.
realloc函数返回指向新内存的指针,对任何类型的变量都是对其的,大小合适的,也可能跟ptr不相同,或者请求失败的时候会返回NULL,如果size是0,会返回NULL,或者能传递给free()的一个独特的指针值,如果realloc失败,以前的内存块不会受到影响,它们不会被释放掉或者被移动。
提示:
By default, Linux follows an optimistic memory allocation strategy. This means that when malloc() returns non-NULL there is no guarantee that the memory really is available. In case it turns out that the system is out of memory, one or more processes will be killed by the OOM killer. For more information, see the description of /proc/sys/vm/overcommit_memory and /proc/sys/vm/oom_adj in proc(5), and the Linux kernel source file Documentation/vm/overcommit-accounting.
在默认情况下,linux使用乐观的内存分配策略,也就是说当malloc返回非NULL并不确保内存的确是可用的,在system out of memory的情况下,一个或多个进程会被OOM killer杀掉,如果需要更多信息,查看/proc/sys/vm/overcommit_memory,/proc/sys/vm/oom_adj和kernel文档/vm/overcommit-accounting的描述。
Normally, malloc() allocates memory from the heap, and adjusts the size of the heap as required, using sbrk(2). When allocating blocks of memory larger than MMAP_THRESHOLD bytes, the glibc malloc() implementation allocates the memory as a private anonymous mapping using mmap(2). MMAP_THRESHOLD is 128 kB by default, but is adjustable using mallopt(3). Allocations performed using mmap(2) are unaffected by the RLIMIT_DATA resource limit (see getrlimit(2)).
正常情况下,malloc()从堆中分配内存,使用sbrk()根据需求调整堆内存的大小,当分配的内存块大于MMAP_THRESHOLD字节的时候,glibc malloc()的实现是用mmap来分配私有匿名内存,MMAP_THRESHOLD的大小默认是128KB,但是可以通过mallopt来调整,用mmap来执行内存分配不受RLIMIT_DATA的影响
To avoid corruption in multithreaded applications, mutexes are used internally to protect the memory-management data structures employed by these functions. In a multithreaded application in which threads simultaneously allocate and free memory, there could be contention for these mutexes. To scalably handle memory allocation in multithreaded applications, glibc creates additional memory allocation arenas if mutex contention is detected. Each arena is a large region of memory that is internally allocated by the system (using brk(2) or mmap(2)), and managed with its own mutexes.
为了避免多线程程序崩溃,这些函数需要内部使用mutex来保护内存管理数据结构,在多线程程序中,多个线程同时分配和释放内存会导致mutex之间产生竞争关系,为了在多线程程序中自如的分配内存,如果检测到mutex竞争,glibc会创建额外的内存分配场地,每个场地拥有使用brk()或者mmap()分配到的一大片内存,使用自己的mutex来管理。
The UNIX 98 standard requires malloc(), calloc(), and realloc() to set errno to ENOMEM upon failure. Glibc assumes that this is done (and the glibc versions of these routines do this); if you use a private malloc implementation that does not set errno, then certain library routines may fail without having a reason in errno.
UINX98标准需要malloc,calloc,realloc在失败的情况下设置errno为ENOMEM,glibc假设这个是已经ok的,如果你使用了一个私人的malloc实现,而且没有设置errno,那么在失败的时候你可能拿不到一个合理的errno
Crashes in malloc(), calloc(), realloc(), or free() are almost always related to heap corruption, such as overflowing an allocated chunk or freeing the same pointer twice.
很简单,没有什么好说的,需要注意的是free只是释放指针所指向的内存,并没有干掉指针变量跟所指向内存之间的关系,所以如果不在free后面跟上一个b = NULL,那么这个指针还能接着使用,但是这是不符合常理的,所以为了规范的编程请free掉指针之后接着赋值为NULL,这样子再用指针的时候会segment fault。
malloc,free,calloc,realloc-动态分配和释放内存
所需头文件
#include <stdlib.h>
void *malloc(size_t size);
void free(void *ptr);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
The malloc() function allocates size bytes and returns a pointer to the allocated memory. The memory is not initialized. If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().
malloc函数分配size byte的内存,并且返回一个指向这块内存的指针,这块内存没有初始化,如果size的大小是0,malloc会返回NULL,或者能传递给free()的一个独特的指针值
The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed.
free()函数通过ptr释放所对应的内存空间,这些内存指针必须是通过malloc,calloc或者relloc返回的,否则,如果之前有调用free方法去释放ptr所对应的指针,那么会发生未定义的行为,如果ptr已经是NULL,那么就什么都不做
The calloc() function allocates memory for an array of nmemb elements of size bytes each and returns a pointer to the allocated memory. The memory is set to zero. If nmemb or size is 0, then calloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().
calloc()函数分配size大小的一系列的nmemb元素,返回指向分配的内存,如果nmemb或者size是0,calloc()返回NULL或者一个能传递给free()的独特的指针值
The realloc() function changes the size of the memory block pointed to by ptr to size bytes. The contents will be unchanged in the range from the start of the region up to the minimum of the old and new sizes. If the new size is larger than the old size, the added memory will not be initialized. If ptr is NULL, then the call is equivalent to malloc(size), for all values of size; if size is equal to zero, and ptr is not NULL, then the call is equivalent to free(ptr). Unless ptr is NULL, it must have been returned by an earlier call to malloc(), calloc() or realloc(). If the area pointed to was moved, a free(ptr) is done.
realloc函数改变通过ptr改变ptr所指向内存块的大小到size byte,ptr原先所指向的内存块里面的内容不会被改变,如果新的size比以前大,那么增加的memory将不会被初始化,如果ptr是NULL,那么等同于malloc(size),不管size的值是多少,如果size是0,ptr不是NULL,那么相当于free(ptr)。如果ptr不是NULL,那么ptr一定是之前malloc,calloc,realloc的返回值,如果所指向的区域被移动了(这个可能是当前区域无法容纳所需要的内存),那么会调用一个free(ptr)来释放以前所占用的区域。
返回值
The malloc() and calloc() functions return a pointer to the allocated memory that is suitably aligned for any kind of variable. On error, these functions return NULL. NULL may also be returned by a successful call to malloc() with a size of zero, or by a successful call to calloc() with nmemb or size equal to zero.
malloc和calloc函数返回一个指针,对任何类型的变量都是对齐的,大小合适的,错误的时候这些函数返回NULL,NULL也可能是0作为malloc参数成功的返回值,或者,nmemb或size为0作为参数成功的返回值
The free() function returns no value.
free函数没有返回值
The realloc() function returns a pointer to the newly allocated memory, which is suitably aligned for any kind of variable and may be different from ptr, or NULL if the request fails. If size was equal to 0, either NULL or a pointer suitable to be passed to free() is returned. If realloc() fails the original block is left untouched; it is not freed or moved.
realloc函数返回指向新内存的指针,对任何类型的变量都是对其的,大小合适的,也可能跟ptr不相同,或者请求失败的时候会返回NULL,如果size是0,会返回NULL,或者能传递给free()的一个独特的指针值,如果realloc失败,以前的内存块不会受到影响,它们不会被释放掉或者被移动。
提示:
By default, Linux follows an optimistic memory allocation strategy. This means that when malloc() returns non-NULL there is no guarantee that the memory really is available. In case it turns out that the system is out of memory, one or more processes will be killed by the OOM killer. For more information, see the description of /proc/sys/vm/overcommit_memory and /proc/sys/vm/oom_adj in proc(5), and the Linux kernel source file Documentation/vm/overcommit-accounting.
在默认情况下,linux使用乐观的内存分配策略,也就是说当malloc返回非NULL并不确保内存的确是可用的,在system out of memory的情况下,一个或多个进程会被OOM killer杀掉,如果需要更多信息,查看/proc/sys/vm/overcommit_memory,/proc/sys/vm/oom_adj和kernel文档/vm/overcommit-accounting的描述。
Normally, malloc() allocates memory from the heap, and adjusts the size of the heap as required, using sbrk(2). When allocating blocks of memory larger than MMAP_THRESHOLD bytes, the glibc malloc() implementation allocates the memory as a private anonymous mapping using mmap(2). MMAP_THRESHOLD is 128 kB by default, but is adjustable using mallopt(3). Allocations performed using mmap(2) are unaffected by the RLIMIT_DATA resource limit (see getrlimit(2)).
正常情况下,malloc()从堆中分配内存,使用sbrk()根据需求调整堆内存的大小,当分配的内存块大于MMAP_THRESHOLD字节的时候,glibc malloc()的实现是用mmap来分配私有匿名内存,MMAP_THRESHOLD的大小默认是128KB,但是可以通过mallopt来调整,用mmap来执行内存分配不受RLIMIT_DATA的影响
To avoid corruption in multithreaded applications, mutexes are used internally to protect the memory-management data structures employed by these functions. In a multithreaded application in which threads simultaneously allocate and free memory, there could be contention for these mutexes. To scalably handle memory allocation in multithreaded applications, glibc creates additional memory allocation arenas if mutex contention is detected. Each arena is a large region of memory that is internally allocated by the system (using brk(2) or mmap(2)), and managed with its own mutexes.
为了避免多线程程序崩溃,这些函数需要内部使用mutex来保护内存管理数据结构,在多线程程序中,多个线程同时分配和释放内存会导致mutex之间产生竞争关系,为了在多线程程序中自如的分配内存,如果检测到mutex竞争,glibc会创建额外的内存分配场地,每个场地拥有使用brk()或者mmap()分配到的一大片内存,使用自己的mutex来管理。
The UNIX 98 standard requires malloc(), calloc(), and realloc() to set errno to ENOMEM upon failure. Glibc assumes that this is done (and the glibc versions of these routines do this); if you use a private malloc implementation that does not set errno, then certain library routines may fail without having a reason in errno.
UINX98标准需要malloc,calloc,realloc在失败的情况下设置errno为ENOMEM,glibc假设这个是已经ok的,如果你使用了一个私人的malloc实现,而且没有设置errno,那么在失败的时候你可能拿不到一个合理的errno
Crashes in malloc(), calloc(), realloc(), or free() are almost always related to heap corruption, such as overflowing an allocated chunk or freeing the same pointer twice.
malloc,calloc,realloc crashes通常是因为heap崩溃了,例如内存溢出或者再次释放已经释放过的指针。
贴一个例子:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
void *a = "hello world";
char *b = NULL;
b = malloc(3);
b = (char *)realloc(b, 12);
strcpy(b, a);
printf("b = %s\n", b);
free(b);
//b = NULL;
printf("b = %s\n", b);
if (b == NULL) {
printf("b is NULL\n");
}
return 0;
}
很简单,没有什么好说的,需要注意的是free只是释放指针所指向的内存,并没有干掉指针变量跟所指向内存之间的关系,所以如果不在free后面跟上一个b = NULL,那么这个指针还能接着使用,但是这是不符合常理的,所以为了规范的编程请free掉指针之后接着赋值为NULL,这样子再用指针的时候会segment fault。