MALLOC - Linux手册页

时间:2019-08-20 17:59:57  来源:igfitidea点击:

Linux程序员手册 第3部分
更新日期: 2020-06-09

名称

malloc,free,calloc,realloc,reallocarray-分配和释放动态内存

语法

#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);
void *reallocarray(void *ptr, size_t nmemb, size_t size);

glibc的功能测试宏要求(请参阅feature_test_macros(7)):

reallocarray():
从glibc 2.29开始:
_DEFAULT_SOURCE
Glibc 2.28及更早版本:
_GNU_SOURCE

说明

malloc()函数分配大小字节,并返回指向分配的内存的指针。内存未初始化。如果size为0,则malloc()返回NULL或一个唯一的指针值,该值以后可以成功传递给free()。

free()函数释放ptr指向的内存空间,该内存空间必须已由先前对malloc(),calloc()或realloc()的调用返回。否则,或者如果之前已经调用过free(ptr),则会发生未定义的行为。如果ptr为NULL,则不执行任何操作。

calloc()函数为每个大小为字节的nmemb元素数组分配内存,并返回指向已分配内存的指针。内存设置为零。如果nmemb或size为0,则calloc()返回NULL或一个唯一的指针值,该值以后可以成功传递给free()。如果nmemb和size的乘积将导致整数溢出,则calloc()将返回错误。相比之下,在对malloc()的以下调用中将不会检测到整数溢出,结果将分配大小错误的内存块:

malloc(nmemb * size);

realloc()函数将ptr指向的内存块的大小更改为大小字节。从区域开始到新旧大小的最小值之间的内容将保持不变。如果新的大小大于旧的大小,则不会初始化添加的内存。如果ptr为NULL,则对于所有size值,该调用等效于malloc(size);否则,该调用等效于malloc(size)。如果size等于零,并且ptr不为NULL,则该调用等效于free(ptr)。除非ptr为NULL,否则它必须已经由对malloc(),calloc()或realloc()的更早调用返回了。如果指向的区域已移动,则执行free(ptr)。

reallocarray()函数将ptr指向的内存块的大小更改为足以容纳nmemb元素数组(每个元素均为大小字节)的大小。相当于通话

realloc(ptr,nmemb * size);

但是,与该realloc()调用不同,在乘法将溢出的情况下,reallocarray()安全地失败。如果发生此类溢出,则reallocarray()返回NULL,将errno设置为ENOMEM,并使原始内存块保持不变。

返回值

malloc()和calloc()函数返回一个指向已分配内存的指针,该指针适合于任何内置类型。错误时,这些函数将返回NULL。成功调用大小为零的malloc()或成功调用nmemb或大小等于零的calloc()也可能返回NULL。

free()函数不返回任何值。

realloc()函数返回一个指向新分配的内存的指针,该指针适合于任何内置类型,如果请求失败,则为NULL。如果分配未移动(例如,有空间可以就地扩展分配),则返回的指针可能与ptr相同,或者如果分配已移动到新地址,则返回的指针可能与ptr不同。如果size等于0,则返回NULL或适合传递给free()的指针。如果realloc()失败,则原始块保持不变;它不会被释放或移动。

成功后,reallocarray()函数将返回一个指向新分配的内存的指针。失败时,它将返回NULL,并且原始内存块保持不变。

错误说明

calloc(),malloc(),realloc()和reallocarray()可能因以下错误而失败:

ENOMEM
内存不足。应用程序可能达到了getrlimit(2)中描述的RLIMIT_AS或RLIMIT_DATA限制。

版本

reallocarray()首次出现在2.26版的glibc中。

属性

有关本节中使用的术语的说明,请参见attribute(7)。

InterfaceAttributeValue
malloc(),free(),
calloc(),realloc()
Thread safetyMT-Safe

遵循规范

malloc(),free(),calloc(),realloc():POSIX.1-2001,POSIX.1-2008,C89,C99。

reallocarray()是一个非标准扩展,最早出现在OpenBSD 5.6和FreeBSD 11.0中。

备注

默认情况下,Linux遵循乐观的内存分配策略。这意味着当malloc()返回非NULL时,不能保证内存确实可用。万一发现系统内存不足,OOM杀手将杀死一个或多个进程。有关更多信息,请参见proc(5)中对/ proc / sys / vm / overcommit_memory和/ proc / sys / vm / oom_adj的描述,以及Linux内核源文件Documentation / vm / overcommit-accounting.rst。

通常,malloc()使用sbrk(2)从堆中分配内存,并根据需要调整堆的大小。当分配大于MMAP_THRESHOLD字节的内存块时,glibc malloc()实现使用mmap(2)将内存分配为私有匿名映射。 MMAP_THRESHOLD默认为128 kB,但可以使用mallopt(3)进行调整。在Linux 4.7之前,使用mmap(2)执行的分配不受RLIMIT_DATA资源限制的影响;从Linux 4.7开始,对使用mmap(2)执行的分配也强制执行此限制。

为了避免多线程应用程序中的损坏,互斥锁在内部用于保护这些功能使用的内存管理数据结构。在线程同时分配和释放内存的多线程应用程序中,这些互斥锁可能存在争用。为了可伸缩地处理多线程应用程序中的内存分配,如果检测到互斥争用,则glibc会创建其他内存分配区域。每个区域都是系统在内部分配的较大内存区域(使用brk(2)或mmap(2)),并使用自己的互斥锁进行管理。

失败时,SUSv2需要malloc(),calloc()和realloc()才能将errno设置为ENOMEM。 Glibc假定已经完成了(这些例程的glibc版本也可以做到这一点)。如果使用未设置errno的私有malloc实现,则某些库例程可能会在没有errno原因的情况下失败。

malloc(),calloc(),realloc()或free()中的崩溃几乎总是与堆损坏有关,例如溢出分配的块或两次释放相同的指针。

malloc()实现可通过环境变量进行调整;有关详细信息,请参见mallopt(3)。

另外参见

valgrind(1),brk(2),mmap(2),alloca(3),malloc_get_state(3),malloc_info(3),malloc_trim(3),malloc_usable_size(3),mallopt(3),mcheck(3), mtrace(3),posix_memalign(3)

有关GNU C库实现的详细信息,请参见

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/