Why this matters: aligned_malloc looks like the smallest problem in the systems set — two functions, one trick — which is exactly why interviewers like it. There is nowhere to hide: either your pointer arithmetic is exact or it isn't, and either you noticed the requirement that forces the bookkeeping or you designed something that can't work. It is the purest specimen of the forcing requirement that Foundations lesson 02 warned about.
The prompt, as given
Implement aligned_malloc and aligned_free.
Your platform's malloc and free work fine, but callers need memory aligned to boundaries stricter than malloc guarantees — SIMD loads, cache-line placement, DMA buffers. You are building the library layer that provides aligned_malloc(size, alignment) and aligned_free(ptr) on top of the existing allocator, which you cannot modify.
The setup grants you a working general-purpose allocator and asks for a thin layer over it. Everything interesting lives in the contract details the prompt doesn't state.
The questions, and why each one matters
"What alignments are legal?" The answer — powers of two, in a practical range — matters twice. First, power-of-two alignment is what makes the round-up a single mask operation. Second, if alignment is caller-supplied, someone must validate it; asking who signals that you treat inputs as part of the contract, not as things that are always polite.
"What does the base malloc guarantee, and may I call it?" You need the baseline (8-byte alignment — the reason this layer exists at all for anything stricter) and the permission: yes, calling malloc and free inside your implementation is the intended design. Without asking, you might waste minutes reinventing a memory source you were meant to reuse.
"What does aligned_free receive?" This is the forcing requirement, and it deserves a beat of respect when the answer lands: only the pointer. No size, no alignment. Whatever tricks you use to produce an aligned address, aligned_free must recover everything it needs — specifically, the original pointer malloc gave you — from the aligned pointer alone. The entire bookkeeping design falls out of this one answer, the same way headers fell out of free-takes-no-size in the general allocator.
"May callers mix this with plain free?" No — memory from aligned_malloc goes to aligned_free, full stop. Worth asking because the answer defines undefined behavior at your boundary, and because a follow-up ("what would detecting misuse cost?") is a classic; having thought about it is cheap insurance.
"How much overhead is acceptable?" A few dozen bytes per allocation: fine. Doubling memory: not. This gives you the budget your design must live inside — and a number you can check your worst case against out loud.
"What about threads?" The layer should add no shared mutable state — whatever thread-safety base malloc has, you inherit; whatever state you add globally, you'd have to lock. The right design adds none.
The requirement set this chapter builds against
alignment caller-supplied power of two (2..4096); MUST be validated
base allocator platform malloc/free; guarantees 8-byte alignment;
calling them inside the layer is the intended design
aligned_free receives ONLY the pointer <- forces bookkeeping
mixing aligned_malloc memory must never reach plain free;
misuse is undefined behavior
overhead bounded and stated; tens of bytes per allocation OK
threading inherit base malloc's; add NO shared mutable state
As always: a live interviewer's answer sheet may differ — a different alignment range, a stricter overhead budget, a different malloc baseline. The conversation is the skill; this set is simply the one the next lessons build against.
Key takeaway
aligned_malloc is two functions and one forcing requirement: aligned_free receives only the pointer, so the layer must be able to recover the original malloc pointer from the aligned address alone. Pin the power-of-two rule (and who validates it), the permission to build on malloc/free, the no-mixing contract, the overhead budget, and the no-shared-state rule — then the design is almost dictated.