a stack allocator
Think of a stack of plates. You add a plate to the top, and you remove plates from the top — last on, first off. A stack allocator brings that discipline to memory: it is an arena that also supports freeing, but only in the exact reverse order of allocation. You can give memory back, but only the most recently allocated chunk, then the next-most-recent, and so on. It is the middle ground between a pure bump arena (free nothing until the end) and a general allocator (free anything in any order).
It works like a bump allocator with one addition: a marker. Allocation moves a top pointer forward, just like an arena. But the allocator also lets you save the current top as a marker, and later free back to that marker, which instantly reclaims everything allocated after it by simply moving the top pointer back to the saved position. This is exactly how nested scopes behave: enter a region, remember the marker; allocate freely inside; on exit, roll back to the marker, releasing the whole batch in constant time. The program's own call stack works on precisely this principle (a function's locals vanish when it returns), which is where the name comes from.
Stack allocators shine for temporary, nested computations: scratch space inside a function, a recursive algorithm that needs working buffers per level, or a per-frame allocator where you push a marker at frame start and pop it at frame end. They are extremely fast and produce no fragmentation, because frees always happen at the top. The strict limit is the LIFO rule itself: if object A is allocated before object B but A must be freed first, a stack allocator simply cannot do it — freeing A would require moving B, which it will not do. When lifetimes do not nest, you need a pool or a general allocator instead.
size_t mark = stack_get_marker(s); /* remember the top */ void *a = stack_alloc(s, 100); void *b = stack_alloc(s, 200); /* ... use a and b ... */ stack_free_to(s, mark); /* frees b THEN a, all at once */ /* trying to free a before b is impossible by design */
Save a marker, allocate freely, then roll the top back to the marker to release the whole batch in LIFO order.
The stack allocator here is a region-of-memory technique; it is not the same thing as the program's call stack, though they share the LIFO idea. Its hard rule is that frees must mirror allocations in reverse order.