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.
So, malloc(0) could return NULL or a valid pointer that may not be dereferenced. In either case, it's perfectly valid to call free() on it.
I don't really think malloc(0) has much use, except in cases when malloc(n) is called in a loop for example, and n might be zero.
Looking at the code in the link, I believe that the author had two misconceptions:
malloc(0) returns a valid pointer always, and
free(0) is bad.
So, he made sure that artist and other variables always had some "valid" value in them. The comment says as much: // these must always point at malloc'd data.
Here is the analysis after running with valgrind memory check tool.
==16740== Command: ./malloc0
==16740==
p1 = 0x5204040
==16740==
==16740== HEAP SUMMARY:
==16740== in use at exit: 0 bytes in 0 blocks
==16740== total heap usage: 2 allocs, 2 frees, 1,024 bytes allocated
==16740==
==16740== All heap blocks were freed -- no leaks are possible
malloc(0) behaviour is implementation specific. The library can return NULL or have the regular malloc behaviour, with no memory allocated. Whatever it does, it must be documented somewhere.
Usually, it returns a pointer that is valid and unique but should NOT be dereferenced. Also note that it CAN consume memory even though it did not actually allocate anything.
It is possible to realloc a non null malloc(0) pointer.
Having a malloc(0) verbatim is not much use though. It's mostly used when a dynamic allocation is zero byte and you didn't care to validate it.
Admittedly, I have never seen this before, this is the first time I've seen this syntax, one could say, a classic case of function overkill. In conjunction to Reed's answer, I would like to point out that there is a similar thing, that appears like an overloaded function realloc:
foo is non-NULL and size is zero, realloc(foo, size);. When you pass in a non-NULL pointer and size of zero to realloc, realloc behaves as if you’ve called free(…)
foo is NULL and size is non-zero and greater than 1, realloc(foo, size);. When you pass in a NULL pointer and size is non-zero, realloc behaves as if you’ve called malloc(…)
Since malloc's return value is implementation dependent, you may get a NULL pointer or some other address back. This can end up creating heap-buffer overflows if error handling code doesn't check both size and returned value, leading to stability issues (crashes) or even worse security issues.
Consider this example, where further accessing memory via returned address will corrupt heap iff size is zero and implementation returns a non NULL value back.
size_t size;
/* Initialize size, possibly by user-controlled input */
int *list = (int *)malloc(size);
if (list == NULL) {
/* Handle allocation error */
}
else {
/* Continue processing list */
}
See this Secure Coding page from CERT Coding Standards where I took the example above for further reading.
The C standard says:
So,
malloc(0)
could returnNULL
or a valid pointer that may not be dereferenced. In either case, it's perfectly valid to callfree()
on it.I don't really think
malloc(0)
has much use, except in cases whenmalloc(n)
is called in a loop for example, andn
might be zero.Looking at the code in the link, I believe that the author had two misconceptions:
malloc(0)
returns a valid pointer always, andfree(0)
is bad.So, he made sure that
artist
and other variables always had some "valid" value in them. The comment says as much:// these must always point at malloc'd data
.Here is the analysis after running with valgrind memory check tool.
and here's my sample code:
By default 1024 bytes is allocated. If I increase the size of malloc, the allocated bytes will increase by 1025 and so on.
malloc(0) behaviour is implementation specific. The library can return NULL or have the regular malloc behaviour, with no memory allocated. Whatever it does, it must be documented somewhere.
Usually, it returns a pointer that is valid and unique but should NOT be dereferenced. Also note that it CAN consume memory even though it did not actually allocate anything.
It is possible to realloc a non null malloc(0) pointer.
Having a malloc(0) verbatim is not much use though. It's mostly used when a dynamic allocation is zero byte and you didn't care to validate it.
Admittedly, I have never seen this before, this is the first time I've seen this syntax, one could say, a classic case of function overkill. In conjunction to Reed's answer, I would like to point out that there is a similar thing, that appears like an overloaded function
realloc
:realloc(foo, size);
. When you pass in a non-NULL pointer and size of zero to realloc, realloc behaves as if you’ve called free(…)realloc(foo, size);
. When you pass in a NULL pointer and size is non-zero, realloc behaves as if you’ve called malloc(…)Hope this helps, Best regards, Tom.
To actually answer the question made: there is no reason to do that
Why you shouldn't do this...
Since malloc's return value is implementation dependent, you may get a NULL pointer or some other address back. This can end up creating heap-buffer overflows if error handling code doesn't check both size and returned value, leading to stability issues (crashes) or even worse security issues.
Consider this example, where further accessing memory via returned address will corrupt heap iff size is zero and implementation returns a non NULL value back.
See this Secure Coding page from CERT Coding Standards where I took the example above for further reading.