Course contentsShow
← Rust
Lesson 346 of 1,9104. Lifetimes and Advanced OwnershipFree lesson

Stack vs Heap Memory Layouts

Visualize memory layout differences to optimize data structure access patterns.

In this lesson, you will learn how the physical layout of your data in memory influences both the performance of your code and the safety guarantees provided by the borrow checker.

The Stack: Predictable and Fast

The stack is a contiguous block of memory that operates like a physical stack of plates. When you declare a variable with a known size at compile time (like an i32 or a struct of primitives), Rust places it on the stack.

Because the stack grows and shrinks as functions are called and return, access is incredibly fast. The CPU simply moves a pointer. However, the stack is rigid; since the size must be known upfront, you cannot easily resize stack-allocated data during runtime.

The Heap: Flexible but Indirected

The heap is a large, unorganized pool of memory used for data with sizes that might change or are unknown at compile time. When you use a collection like Vec<T> or a Box<T>, you are placing data on the heap.

The heap requires a two-step lookup:

  1. The stack stores a small, fixed-size pointer (the address), the length, and the capacity of your data.
  2. The heap holds the actual, larger data stored at that address.
fn main() {
    let x = 10;            // Stack: 4 bytes of memory
    let y = Box::new(20);  // Stack: A pointer to the heap; Heap: The value 20
}

Optimizing Access Patterns

Understanding this layout is crucial for performance. When you iterate over a Vec<i32>, the processor enjoys "spatial locality"—it can pre-fetch a chunk of heap memory because the integers are packed tightly together.

If you use a Vec<Box<T>>, however, your data is scattered across the heap. Your CPU must "chase pointers" to jump to different memory locations, which often results in cache misses. By keeping your data on the stack or in contiguous heap structures, you minimize these jumps and keep your program running smoothly.

Key Takeaway: Prefer stack allocation for fixed-size, frequently accessed data, and reserve heap allocation for dynamic data, keeping in mind that pointer indirection is the cost of that flexibility.