Master the fundamental concepts of c programming deep dive through this focused micro-challenge.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksmalloc on glibc returns 16-byte aligned memory because SSE and AVX loads fault or slow down on misaligned addresses. An int wants 4-byte alignment; a double wants 8. The check is simple: (uintptr_t)ptr % align == 0.
Aligned heap block: over-allocate, bump the pointer up to the next aligned boundary, stash the original malloc pointer just before the aligned region so free can find it:
cLoading…
Stack bump allocator: advance a current pointer through a fixed buffer; pop resets it. LLVM and game engines use this pattern for per-pass temporaries.
free on the stack side, only resetFor this exercise, you will implement aligned_malloc, aligned_free, and a small stack allocator with push/pop. This task asks you to verify alignment with uintptr_t checks, because mysterious SIMD crashes in production are almost always an alignment bug.
Keep the relevant man page, ABI doc, or Rust reference chapter open while you work. When your output disagrees with the reference implementation on the same machine, the mismatch is usually an alignment rule, an off-by-one terminator, or a register slot you misread in GDB.
Write two allocators that respect alignment.
aligned_malloc(size, alignment) / aligned_free(ptr). Over-allocate with malloc(size + alignment + sizeof(void *)). Round the address just past a pointer-sized slot up to the alignment, and store the original malloc pointer in the slot right before the returned address. aligned_free reads that slot back and frees the original pointer.
A stack allocator over one 4096-byte buffer, tracking an offset:
push(size, alignment): round the offset up to the alignment, (offset + a - 1) & ~(a - 1), where a is a power of two. Return that position and advance the offset past the allocation. Return NULL if it would pass the end.pop(ptr): the offset goes back to ptr, freeing it and everything pushed after it.free: release the buffer.Offsets are relative to the buffer, so the byte counts below are the same on every machine.
One word selecting a scenario.
aligned (and free, which runs the same scenario): allocate an int with alignment 8 and a double with alignment 16, store 42 and 3.14, check alignment, free both:cLoading…
stack: push 10 ints (alignment 8), then 5 doubles (alignment 16). The second push starts at offset 48, not 40:cLoading…
pop: the same two pushes, then pop the doubles:cLoading…
aligned, stack and pop scenarios in that order.