This behavior is implementation defined.
From the C standard:
Section 7.22.3.5 (realloc):
3 If ptr is a null pointer, the realloc function behaves like the malloc function for the specified size. Otherwise, if ptr
does not match a pointer earlier returned by a memory management
function, or if the space has been deallocated by a call to
the free or realloc function, the behavior is undefined. If
memory for the new object cannot be allocated, the old object is
not deallocated and its value is unchanged.
So realloc(NULL, 0) is the same as malloc(0)
If we then look at section 7.22.3.4 (malloc):
2 The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.
3 The malloc function returns either a null pointer or a pointer to the allocated space.
The standard does not state what happens when 0 is passed in.
But if you look at the Linux man page:
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().
It explicitly states that the returned value can be freed but is not necessarily NULL.
In contrast, MSDN says:
If size is 0, malloc allocates a zero-length item in the heap and
returns a valid pointer to that item. Always check the return from
malloc, even if the amount of memory requested is small.
So for MSVC, you won't get a NULL pointer.