Skip to content

Rust Basics - Memory

Rust Basics - Memory

Understanding memory management is fundamental to becoming proficient in Rust. Unlike languages with garbage collection, Rust gives you fine-grained control over memory while ensuring safety through its ownership system.

Stack vs Heap

The Stack

The stack stores values in the order it gets them and removes them in the opposite order. This is referred to as last in, first out (LIFO). Adding data is called pushing onto the stack, and removing data is called popping off the stack.

fn main() {
    let x = 5;  // Stored on the stack
    let y = 10; // Also on the stack
}

Stack data must have a known, fixed size.

The Heap

The heap is less organized: when you put data on the heap, you request a certain amount of space. The memory allocator finds an empty spot that's big enough, marks it as being in use, and returns a pointer.

fn main() {
    let s = String::from("hello"); // Stored on the heap
    // s is a pointer on the stack pointing to data on the heap
}

Ownership Rules

Rust's memory safety guarantees are enforced at compile time via ownership:

  1. Each value has an owner
  2. There can only be one owner at a time
  3. When the owner goes out of scope, the value is dropped

RAII in Rust

Rust follows the Resource Acquisition Is Initialization (RAII) pattern:

{
    let s = String::from("hello"); // s is valid from this point forward
    // do stuff with s
}   // this scope is now over, and s is no longer valid
     // the memory is automatically freed here

Static Memory

Static memory contains data that lasts for the entire lifetime of the program:

static HELLO: &str = "Hello, world!";
const MAX_POINTS: u32 = 100_000;

Summary

| Memory Type | Speed | Size | Lifetime | |-------------|-------|------|----------| | Stack | Very fast | Fixed | Scope | | Heap | Slower | Dynamic | Until dropped | | Static | Fast | Fixed | Program |

Understanding these concepts is crucial for writing efficient and safe Rust code!