Project 2: Memory Arena Allocator (Own Your Own Memory)

A custom memory arena allocator that pre-allocates a large block of memory and hands out chunks from it—demonstrating manual memory management while staying safe with Rust’s type system.

Quick Reference

Attribute Value
Primary Language Rust
Alternative Languages C, C++
Difficulty Level 3: Advanced
Time Estimate 1-2 weeks
Knowledge Area Memory Management / Allocators / Unsafe Rust
Tooling Rust std library, custom allocator API
Prerequisites Project 1 completed, basic understanding of pointers and memory layout

What You Will Build

A custom memory arena allocator that pre-allocates a large block of memory and hands out chunks from it—demonstrating manual memory management while staying safe with Rust’s type system.

Why It Matters

This project builds core skills that appear repeatedly in real-world systems and tooling.

Core Challenges

  • Implementing allocation without the standard allocator → maps to understanding what malloc/free actually do
  • Using unsafe correctly with raw pointers → maps to understanding Rust’s safety boundary
  • Ensuring memory alignment → maps to CPU memory access requirements
  • Preventing use-after-free in your API design → maps to leveraging the type system for safety

Key Concepts

  • Unsafe Rust: “The Rust Programming Language” Chapter 19 - Steve Klabnik
  • The Global Allocator trait: “Rust for Rustaceans” Chapter 10 - Jon Gjengset
  • Memory alignment: “Computer Systems: A Programmer’s Perspective” Chapter 3 - Bryant & O’Hallaron
  • Arena allocation pattern: “Programming Rust, 2nd Edition” Chapter 21 - Jim Blandy

Real-World Outcome

// Your arena in action
fn main() {
    // Create a 1MB arena
    let arena = Arena::new(1024 * 1024);

    // Allocate from the arena (fast: just bump a pointer!)
    let name: &mut String = arena.alloc(String::from("Alice"));
    let numbers: &mut [i32] = arena.alloc_slice(&[1, 2, 3, 4, 5]);

    println!("Name: {}", name);
    println!("Sum: {}", numbers.iter().sum::<i32>());

    // Everything freed at once when arena is dropped
    // No individual frees, no fragmentation!
}

// Output:
// Name: Alice
// Sum: 15
// Arena stats: allocated 89 bytes from 1048576 byte pool

Implementation Guide

  1. Reproduce the simplest happy-path scenario.
  2. Build the smallest working version of the core feature.
  3. Add input validation and error handling.
  4. Add instrumentation/logging to confirm behavior.
  5. Refactor into clean modules with tests.

Milestones

  • Milestone 1: Minimal working program that runs end-to-end.
  • Milestone 2: Correct outputs for typical inputs.
  • Milestone 3: Robust handling of edge cases.
  • Milestone 4: Clean structure and documented usage.

Validation Checklist

  • Output matches the real-world outcome example
  • Handles invalid inputs safely
  • Provides clear errors and exit codes
  • Repeatable results across runs

References

  • Main guide: LEARN_RUST_DEEP_DIVE.md
  • “Rust for Rustaceans” by Jon Gjengset