STANFORD CS107 / WINTER 2025 / SYSTEMS PROGRAMMING
Heap Allocator
A custom implementation of malloc, free, and realloc built in C for CS107, focused on correctness, memory utilization, and performance tradeoffs.
ROLE
Student / Systems Programmer
TOOLS
C, pointer arithmetic, debugging, profiling, memory management
TIMELINE
Winter 2025
CONTEXT
Final project for Stanford CS107: Computer Organization & Systems
01 / PROJECT OVERVIEW
What this project was
This project was my final assignment for Stanford CS107, where I built my own heap allocator from scratch. The goal was to implement core memory management functionality equivalent to malloc, free, and realloc, while balancing correctness, speed, and memory efficiency.
The assignment involved building two allocator designs: an implicit free list allocator and an explicit free list allocator. That made the project not just about getting something working, but about understanding the tradeoffs between different system designs and making implementation decisions that affected performance.
02 / THE PROBLEM
Why this mattered
All quarter in CS107, I had been using the heap indirectly through dynamic memory allocation. This project flipped that perspective and forced me to go under the hood. Instead of treating memory allocation as a black box, I had to design the data structures and logic that make the heap usable in the first place.
The challenge was that a heap allocator has competing goals. It needs to be correct for arbitrary well-formed requests, compact in how it uses memory, and fast enough to serve allocations efficiently. Those goals naturally create tradeoffs, so the project became an exercise in systems thinking as much as implementation.
03 / DESIGN APPROACH
How I framed the allocator
I approached the assignment by thinking carefully about allocator structure before writing code. For the implicit free list allocator, I focused on understanding block layout, header metadata, alignment, and traversal through contiguous memory. For the explicit free list allocator, I then extended that thinking to track free blocks more directly and improve efficiency.
A big part of the design process was reasoning about tradeoffs. An allocator can move quickly by doing less bookkeeping, but that often wastes memory. On the other hand, aggressively reusing and packing blocks can improve utilization while increasing implementation complexity. This project forced me to think about those tradeoffs in a very concrete way.
04 / WHAT I BUILT
Allocator functionality
I implemented custom versions of malloc, free, and realloc, along with the supporting heap logic needed to manage block allocation, deallocation, splitting, reuse, and traversal. The project required handling well-formed request patterns while preserving consistency of the heap structure across many possible allocation sequences.
The explicit free list version pushed things further by tracking free blocks in a more structured way, which improved performance compared to a purely implicit scan. That progression made it easier to see how different allocator designs impact both runtime behavior and memory utilization.
05 / HARD SKILLS
Systems + technical growth
- Implementing heap allocation logic in C
- Working directly with pointers, offsets, and memory layout
- Reasoning about block headers, alignment, and heap invariants
- Comparing implicit and explicit free list designs
- Profiling code and thinking through utilization vs. speed tradeoffs
06 / SOFT SKILLS
Problem solving + persistence
- Breaking a complex systems problem into smaller design decisions
- Debugging patiently when small pointer mistakes caused major failures
- Thinking in terms of tradeoffs instead of “one perfect solution”
- Using iteration to improve both correctness and performance
- Building confidence working closer to the machine level
07 / KEY VISUAL
Allocator model
This diagram captures the core mental model behind the project: memory blocks on the heap must be organized, tracked, and reused in a way that balances correctness with efficiency.

A visual representation of allocator structure, showing how memory blocks and management logic interact inside the heap.
08 / LEARNING GOALS
What this project taught me
This assignment helped me appreciate how much complexity sits behind something as common as dynamic memory allocation. It strengthened my pointer skills, forced me to debug carefully, and made performance profiling feel much more meaningful because every design choice had a visible consequence.
More broadly, it brought together a lot of what I learned in CS107: reasoning about memory, designing around constraints, and thinking critically about efficiency. It was one of those projects that made systems programming feel much more real and much more rewarding.
09 / TAKEAWAYS
What stuck with me
What I liked most about this project was that it made tradeoffs feel tangible. You cannot optimize everything at once, so you have to reason about what matters most and why. That mindset applies far beyond allocators — it is really a broader lesson in engineering design.
It also made me more comfortable with lower-level programming. Building a heap allocator from scratch was difficult, but it gave me a much stronger intuition for how memory systems actually work and why careful systems design matters.
