C's malloc() and free() APIs are reasonable APIs for C

September 10, 2022

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.)

Written on 10 September 2022.
« How we monitor the temperature of our machine rooms
The amount of memory in basic 1U servers and our shifting views of it »

Page tools: View Source.
Search:
Login: Password:

Last modified: Sat Sep 10 22:09:13 2022
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.