malloc(0)时程序会返回什么?
扫描二维码
随时随地手机看文章
7.22.3 节里,有如下说法:The order and contiguity of storage allocated by successive calls to the aligned_alloc, calloc, malloc, and realloc functions is unspecified. The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement and then used to access such an object or an array of such objects in the space allocated (until the space is explicitly deallocated). The lifetime of an allocated object extends from the allocation until the deallocation. Each such allocation shall yield a pointer to an object disjoint from any other object. The pointer returned points to the start (lowest byte address) of the allocated space. If the space cannot be allocated, a null pointer is returned. If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned to indicate an error, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.在这里,标准委员会明确规定了:当
malloc 接到的参数为 0 时,其行为是由实现定义的(implementation-defined)。由实现定义的行为这个词就提醒我们,在实际编程时如果要考虑到程序在多个运行环境下进行运行时,不能对
malloc 返回的数值进行任何假设。换言之,没事儿不要吃饱了撑的在实际编程中写下 malloc(0) 这种天怒人怨的代码。
glibc 的源代码,依此了解在
glibc 下,
mallloc(0) 的行为。在
glibc2.27/malloc/malloc.c 中,有如下注释:/*
malloc(size_t n)
Returns a pointer to a newly allocated chunk of at least n bytes, or null
if no space is available. Additionally, on failure, errno is
set to ENOMEM on ANSI C systems.
If n is zero, malloc returns a minumum-sized chunk. (The minimum
size is 16 bytes on most 32bit systems, and 24 or 32 bytes on 64bit
systems.) On most systems, size_t is an unsigned type, so calls
with negative arguments are interpreted as requests for huge amounts
of space, which will often fail. The maximum supported value of n
differs across systems, but is in all cases less than the maximum
representable value of a size_t.
*/
注释已经说的很清楚了,当我们执行
malloc(0) 时,我们实际会拿到一个指向一小块内存的指针,这个指针指向的(分配给我们的)内存的大小是由机器决定的。细读代码,可以发现,将读入的内存大小进行转换是由宏
checked_request2size 实现的。相关的宏定义如下:/* pad request bytes into a usable size -- internal version */
#define request2size(req) \
(((req) SIZE_SZ MALLOC_ALIGN_MASK