Why this matters: the arena allocator is the gentlest entry into systems-programming LLD, and also the purest test of a skill the whole flavor runs on: reading a contract and understanding what it buys. The prompt hides one enormous question — does free(ptr) exist? — and how you handle that question's answer decides whether you build the right allocator or a slow imitation of malloc.
The prompt, as given
Implement an arena allocator — one where an allocation is meant to cost little more than bumping a pointer, and memory is reclaimed all at once rather than object by object.
Allocators like this power request handlers, frame loops, parsers and compilers, and they occupy a very different point in the design space from a general-purpose malloc: they are fast precisely because of what they refuse to do. Part of your job is to be able to say where an arena is the right tool and where it is the wrong one.
The prompt tells you the destination — pointer-bump allocation, bulk reclamation — but leaves the contract wide open. What may a caller assume? What happens when memory runs out? What does "reclaim" even mean here? Those answers are yours to go and get.
The questions, and why each one matters
"Is there an individual free?" Ask this first, because everything else hangs on it. The interviewer will say no — and the important part is what you say next. The wrong reaction is to treat no-free as a limitation to apologize for. The right reaction is to recognize it as the feature: because no object is ever released alone, the allocator never tracks per-object state, and that refusal is exactly what makes allocation a pointer bump. An interviewer is listening for whether you understand that the contract's restriction is the performance.
"What alignment do callers get?" Raw bytes handed out at arbitrary offsets will crash real callers. Pinning the default (and whether a caller can ask for stricter) decides arithmetic you'll write in the very first function.
"What happens when the current memory runs out?" Fail, or grow? If the arena grows, how — and does an allocation larger than a whole block have to succeed? That last case is easy to design out by accident, so surface it now.
"What exactly does reset mean?" "Reclaimed all at once" could mean returning memory to the OS, or keeping it warm for the next phase. The difference shapes the API: a reset() that reuses blocks and a destroy() that releases them are different promises.
"Who calls this — one thread or many?" For an arena the idiomatic answer isn't a lock; it's one arena per thread. Asking shows you know arenas are usually private to a phase or a worker, not shared infrastructure.
"What does the size profile look like?" Mostly-small allocations justify the bump design; a tail of oversized requests forces a plan for them.
The requirement set this chapter builds against
free(ptr) does not exist — everything allocated dies together
alignment every allocation >= 8-byte aligned;
callers may request a larger power-of-two alignment
growth current block exhausted -> chain a new block;
initial block 64 KiB; exhaustion must not fail
oversized a request larger than a whole block must still succeed
reset() empties the arena for reuse, KEEPS the memory warm
destroy() actually releases everything
threading single-threaded per arena (one arena per thread idiom)
size profile mostly tens-to-hundreds of bytes
Read the table the way lesson 02 of Foundations taught: several of these answers are forcing. No-free plus bulk reset forces the arena to track nothing per object. "Exhaustion must not fail" forces a growth mechanism. "Oversized must succeed" forces a path that doesn't assume requests fit in a standard block. The design in the next lesson is largely these forces made concrete.
And — as with every chapter in this course — a live interviewer's answers may differ from this set. Theirs might grow by doubling, or fix the arena size entirely, or demand 16-byte default alignment. The conversation is the skill; this particular sheet is just the one we'll build against.
Key takeaway
The arena's defining requirement is the one it refuses: there is no individual free, and understanding that refusal as the feature that buys pointer-bump speed — not a flaw to apologize for — is the core signal of this problem. Pin the contract: alignment, growth on exhaustion, oversized requests, reset-versus-destroy semantics, and one-arena-per-thread, then let those promises force the design.