C's malloc()
and free()
APIs are reasonable APIs for C
I've written about how the free()
API means that C memory
allocation needs to save some metadata, and
before that about the effects of malloc()
and free()
on C
APIs. However, despite these issues I think
that C's malloc()
and free()
APIs are reasonable ones for C to
have, and probably that they've helped C remain relevant over the
years.
To start with, both malloc()
and free()
have what I could call
a minimal API, where they take only the arguments that are really
needed; in the case of both, this is one argument each. You can't
allocate memory without saying how much in some way, and you can't
free memory without saying what to free, so it's hard to get a
smaller API without some form of automatic handling of memory
(including Rust's automatic lifetime management). Having memory
allocation as an explicit API has also meant that you can readily
write C code that doesn't allocate memory (except on the stack),
or use entirely different allocation functions that you built
yourself. Both OS kernels and embedded code tend to use something
completely different from malloc() and free().
That you don't have to pass a length (or any other qualifier) to
free()
is also a good fit with C's approach to strings, which
don't have an explicit length field. Certain sorts of C code
frequently deal with allocated strings of uncertain length and wind
up freeing them; if free()
required an explicit length, there
would be a lot of additional strlen()
calls. I think that the C
malloc()
and free()
API (and realloc()
) is a quite good fit
as a simple string-focused memory allocator.
That C's memory allocation APIs are so minimal has allowed for a lot of experimentation with some approaches to memory allocation. There are a lot of more complicated allocators that can be hid behind the C API, for things like size class based allocation and so on. A more feature-rich API (for example, one that had an explicit idea of 'arenas') might have foreclosed certain sorts of internal implementations, or at least made them more complicated.
(It's worth noting at this point that on most Unixes, the internals of C memory allocation were completely changed over the course of time, from sbrk() to mmap(). Nothing really noticed.)
Within the constraints of being a simple and general API and allowing
relatively simple and efficient implementation on small systems
(which is what Unix and C started on), I think that malloc()
,
free()
, and their friends are at least a decent API. They've
certainly proven to be remarkably durable and functional; although
there are alternate implementations (and modern C libraries generally
use much more complicated approaches), no alternate API has really
caught on.
(Well, at least on Unix. My knowledge of Windows, macOS, and mobile environments is limited.)
|
|