If `malloc(0)` returns a non-null pointer, can I pass that to `free`? If `malloc(0)` returns a non-null pointer, can I pass that to `free`? c c

If `malloc(0)` returns a non-null pointer, can I pass that to `free`?


The C99 standard (actually WG14/N1124. Committee Draft -- May 6, 2005. ISO/IEC 9899:TC2) says about malloc():

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, 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

and about free():

Otherwise, if the argument does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

IEEE Std 1003.1-2008 (POSIX), 2016 Edition says about free():

The free() function shall cause the space pointed to by ptr to be deallocated; that is, made available for further allocation. If ptr is a null pointer, no action shall occur. Otherwise, if the argument does not match a pointer earlier returned by a function in POSIX.1-2008 that allocates memory as if by malloc(), or if the space has been deallocated by a call to free() or realloc(), the behavior is undefined.

So, whatever *alloc() returns, you can pass to free().

As for the current implementations of malloc():

FreeBSD uses the contributed jemalloc which does

void *je_malloc(size_t size){    void *ret;    size_t usize JEMALLOC_CC_SILENCE_INIT(0);    if (size == 0)        size = 1;    [...]

Whereas Apple's libmalloc does

void *szone_memalign(szone_t *szone, size_t alignment, size_t size){    if (size == 0) {        size = 1; // Ensures we'll return an aligned free()-able pointer    [...]

The GLIBC also changes the requested size; it is using a call to this macro with the requested size in bytes as the parameter to align the size to a certain boundary or simply the minimum allocation size:

#define request2size(req)                                       \    (((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE)  ?         \    MINSIZE :                                                   \    ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)


Yes, in fact you must do so to avoid a probable memory leak.

The malloc system typically returns a hidden control block in the space immediately before the pointer, with information such as allocation size. If allocation size is zero, this block still exists and occupies memory, if malloc returns non-null.