free() API gives libraries and functions useful freedom
A while back I wrote about how free()s API means that (C) memory allocation has to save some metadata, either explicitly or implicitly, because you don't pass in the size of what you're freeing. I happen to feel that this is still a decent API for C, but beyond that there's another little advantage to this API, which is that no one needs to know how big an allocated object is. There are at least three uses for this.
The first use is the one traditionally used by advanced C memory
allocation systems. Many allocations (especially for small sizes)
will have their size rounded up a bit, leaving extra unused space
behind the returned object. If this object is then passed to
realloc(), it's possible for it to be reallocated larger in place,
without any memory copying having to be done. The
specifically allows this behavior, and doesn't require that a
different pointer be returned than was passed in.
(Realloc can also be used to shrink the allocation, which can easily be done in place, although I think that usage is a lot less common.)
The second use is that a library can (theoretically) transparently expand the size of an object that it returns and that you free later yourself, especially if the object and its size is completely opaque. Similarly, a library can actually return several differently sized objects that you treat uniformly; as far as you're concerned they're a black box that you eventually call free() on. There are some cautions in practice, since C programmers have traditionally been very ingenious about finding ways to actually depend on the size of the thing you return.
(C strings are kind of this; things that return dynamically allocated strings generally don't promise that they'll be any specific size.)
The third use is what some people proposed as the solution to how
malloc() and free() affect C APIs in the
gethostbyname(). Although a 'struct hostent' contains
pointers to various other things, you can pack all of those things
together into a single memory allocation that has the 'struct
hostent' at the start (effectively you allocate a little arena and
then manually manage it). Because this is a single memory allocation,
you can return a single pointer to it and the caller can still free
everything with a single call to
I'm not convinced that this is a good API, but it's certainly one
that free()'s API makes possible.