... You have two main choices,
corresponding to the implementation's choices for malloc(0):
1. make it always act the way it would if malloc(0) were null ... ....
2. make it always act the way it would if malloc(0) were to behave the
same as malloc(n) for some non-zero value of n: ...
It occurs to me that there's a third option, not allowed by the standard
for malloc(), that is available for your wrapper. It relies upon a new
C2011 feature, max_align_t, to ensure that the pointer is correctly
aligned for conversion to any type. If the code cannot rely on C2011, a
more complicated approach is required.
malloc_wrapper.h:
#ifndef H_MALLOC_WRAPPER
#define H_MALLOC_WRAPPER
#include <stdlib.h>
extern void * const zero_alloc;
void *malloc_wrapper(size_t);
void free_wrapper(void *);
#endif
malloc_wrapper.c:
#include "malloc_wrapper.h"
#include <stddef.h>
static max_align_t dummy;
void * zero_alloc = &dummy;
void *malloc_wrapper(size_t size)
{
return size ? malloc(size) : zero_alloc;
}
void free_wrapper(void *ptr)
{
if(ptr != zero_alloc)
free(ptr);
}
In the unlikely event that your program makes large numbers of
zero-sized allocations, the memory not wasted by this wrapper could be
significant - but you need to be very careful to not call free(p), if
it's possible that p==zero_alloc.