Memory Concepts in Rust

Stack vs. Heap

Stack

  • Fast, fixed-size memory allocation
  • LIFO (Last In, First Out) access pattern
  • Data with known, fixed size at compile time
  • Automatically deallocated when variables go out of scope
fn main() {
    // Stack allocated: fixed size known at compile time
    let x = 42;        // Integer (i32)
    let y = true;      // Boolean
    let z = 3.14;      // Float (f64)
}
// x, y, z automatically deallocated here

Heap

  • Dynamic size memory allocation
  • Access via pointers
  • Explicit allocation (though Rust manages this)
  • Lives until explicitly deallocated
fn main() {
    // Heap allocated: size determined at runtime
    let s = String::from("hello"); // Data stored on heap, pointer on stack

    // Heap memory for "hello" is freed automatically when s goes out of scope
}

Memory Layout

Stack Variables

fn main() {
    let a = 5;     // 4 bytes directly on stack
    let b = 10;    // 4 bytes directly on stack

    // Stack frame contains 8 bytes total
}

Heap Variables

fn main() {
    let s1 = String::from("Hello"); // Stack contains pointer, length, capacity
                                     // Heap contains the actual string data

    // s1 on stack: [pointer_addr | 5 | 5]
    //      pointer_addr points to heap memory containing "Hello"
}

Memory Allocation

Rust automatically handles memory allocation and deallocation through its ownership system:

fn main() {
    // Allocation happens automatically
    {
        let s = String::from("hello"); // Memory allocated
        // s can be used here
    } // s goes out of scope, memory automatically deallocated
}

Memory Safety Challenges

In addition to protect from memory leaks, Rust prevents common memory problems:

1. Double Free

// Not possible in safe Rust:
let s1 = String::from("hello");
let s2 = s1; // s1 is moved, no longer valid
// drop(s1); // Error: use of moved value

2. Dangling References

// Compiler prevents this:
fn dangling() -> &String {
    let s = String::from("hello");
    &s // Error: returns reference to data owned by current function
}