Why is the first C++ (m)allocation always 72 KB?
TLDR; The C++ standard library sets up exception handling infrastructure early on, allocating memory for an “emergency pool” to be able to allocate memory for exceptions in case malloc ever runs out of memory.
Introduction
I like to spend (some of) my time hacking and experimenting on custom memory allocators with my own malloc implementation(s). While unit tests are useful for correctness, the ultimate test is seeing how the allocator behaves in real-world programs. On Linux, overriding the default malloc is surprisingly simple: wrap the standard allocation functions (e.g., malloc, calloc, realloc, free, and utilities like malloc_usable_size), compile your implementation into a shared library, and use LD_PRELOAD to force programs to load it first. For example, you can test your allocator with a simple command like this:
LD_PRELOAD = /home/joel/mymalloc/libmymalloc.so ls
To better understand how programs allocate memory, I built a debug tool that logs the size of every allocation request to a file. You have to be careful when creating debug tools like this when implementing malloc to not internally use malloc to log output. Otherwise, you risk an infinite loop and a crash. To solve this I’m using a stack-allocated buffer together with low-level functions like creat, write and snprintf to safely capture the data.
$ LOG_ALLOC = log.txt LD_PRELOAD = /home/joel/mymalloc/libmymalloc.so ls
The 72 KB Mystery
While analyzing allocation patterns across different programs, I noticed something unusual: the very first allocation is always 73728 bytes (72 KB). Every program I tested exhibited this behavior, as confirmed by my debug logs:
$ head -n 1 log.txt 73728
... continue reading