HN
Today

Why is the first C++ (m)allocation always 72 KB?

A curious C++ developer uncovers why the very first allocation in a C++ program is consistently 72 KB, a persistent mystery for those working with custom memory allocators. It turns out libstdc++ preemptively reserves an 'emergency pool' for exception handling, a subtle but crucial detail for system-level debugging and understanding C++ runtime behavior. This deep dive into a common but opaque system quirk resonates with HN's audience who appreciate unraveling low-level technicalities.

6
Score
0
Comments
#4
Highest Rank
12h
on Front Page
First Seen
Mar 1, 10:00 AM
Last Seen
Mar 1, 9:00 PM
Rank Over Time
64561115161819192230

The Lowdown

The author, while developing custom memory allocators and debugging their behavior, consistently observed a curious phenomenon: the very first C++ memory allocation was always 72 KB. This article chronicles their journey to unravel this mystery, highlighting the tools and techniques used to trace the allocation back to its source.

  • The investigation began by using a custom LD_PRELOAD malloc wrapper with logging, and then gdb to inspect the call stack of the first 72 KB allocation.
  • The backtrace pointed to libstdc++.so.6, specifically to __gnu_cxx::__pool_alloc_base::_M_allocate_chunk.
  • Further drilling down into the libstdc++ source code, the allocation was pinpointed to libsupc++/eh_alloc.cc, revealing it's for an "emergency pool" used in exception handling.
  • This emergency pool ensures that exceptions can still be allocated and thrown even if the primary malloc fails, acting as a critical fallback mechanism.
  • The 72 KB size is derived from internal libstdc++ tunables like EMERGENCY_OBJ_SIZE and EMERGENCY_OBJ_COUNT, which are based on system word size and can be modified via GLIBCXX_TUNABLES.
  • The author demonstrates how changing these tunables alters the initial allocation size, confirming the emergency pool's role.
  • This finding also sheds light on confusing Valgrind reports where this memory was often marked as "still reachable," a behavior addressed in newer Valgrind versions by explicitly freeing the pool during program shutdown.

This deep dive demonstrates the intricate dance of memory management within the C++ runtime, where seemingly arbitrary behaviors like an initial 72 KB allocation are in fact carefully designed low-level system safeguards. It serves as a testament to the complexity and hidden mechanisms beneath everyday programming.