Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the return value of malloc(0) implementation-defined?

ISO/IEC 9899:TC2 (i.e. the C99 standard), §7.20.3 states:

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.

In other words, malloc(0) may either return NULL or a valid pointer which I may not dereference.

What is the rationale behind this behavior?
And wouldn't it be easier to just define that malloc(0) leads to UB?

like image 828
Philip Avatar asked Mar 21 '11 00:03

Philip


People also ask

What is the return value of malloc 0?

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().

Why is malloc returning NULL?

Malloc will return NULL when the kernel/system lib are certain that no memory can be allocated. The reason you typically don't see this on modern machines is that Malloc doesn't really allocate memory, but rather it requests some “virtual address space” be reserved for your program so you might write in it.

What happens if you pass 0 to malloc?

The result of calling malloc(0) to allocate 0 bytes is implementation-defined. In this example, a dynamic array of integers is allocated to store size elements. However, if size is 0, the call to malloc(size) may return a reference to a block of memory of size 0 instead of a null pointer.

Do you have to free malloc 0?

Yes, free(malloc(0)) is guaranteed to work.


1 Answers

The C99 Rationale (PDF link) discusses the memory management functions (from C99 7.20.3) and explains:

The treatment of null pointers and zero-length allocation requests in the definition of these functions was in part guided by a desire to support this paradigm:

OBJ * p; // pointer to a variable list of OBJs
    /* initial allocation */
p = (OBJ *) calloc(0, sizeof(OBJ)); 
    /* ... */
    /* reallocations until size settles */
while(1) { 
    p = (OBJ *) realloc((void *)p, c * sizeof(OBJ)); 
      /* change value of c or break out of loop */
} 

This coding style, not necessarily endorsed by the Committee, is reported to be in widespread use.

Some implementations have returned non-null values for allocation requests of zero bytes.
Although this strategy has the theoretical advantage of distinguishing between "nothing" and "zero" (an unallocated pointer vs. a pointer to zero-length space), it has the more compelling theoretical disadvantage of requiring the concept of a zero-length object.

Since such objects Library cannot be declared, the only way they could come into existence would be through such allocation requests.

The C89 Committee decided not to accept the idea of zero-length objects. The allocation functions may therefore return a null pointer for an allocation request of zero bytes. Note that this treatment does not preclude the paradigm outlined above.

QUIET CHANGE IN C89: A program which relies on size-zero allocation requests returning a non-null pointer will behave differently.

like image 64
James McNellis Avatar answered Oct 02 '22 16:10

James McNellis