Skip to content

Beginner · Ownership: Rust's big idea · topic 10 of 50 · 30 min

Memory 101: the stack and the heap

Explanation

A running program keeps data in two places: the stack, which is fast and holds values of a fixed, known size, and the heap, which holds data that can grow, like text and lists. Heap memory must be freed exactly once. Mistakes here cause crashes and security holes in C, and slow garbage collection in Java; Rust solves it with ownership.

Why learn about memory at all?

In Python or JavaScript you rarely think about memory. Rust is different: its rules about ownership exist to manage memory safely without a garbage collector. To understand the rules, you need a simple picture of where data lives. Memory is the computer's working space (RAM), where a running program keeps its values.

The stack

The stack is a region of memory that works like a pile of plates. When a function starts, a new plate (called a stack frame) is put on top, holding that function's local variables. When the function ends, its plate is taken off and everything on it is gone. Adding and removing is extremely fast, but there is a rule: everything on the stack must have a size known at compile time, such as an i32 (4 bytes), a bool (1 byte) or an array [u8; 16].

output
fn main() {            STACK (grows upward)
    let a = 5;          +-------------------+
    let b = true;       | square: n = 5     |  <- removed when square ends
    square(a);          +-------------------+
}                       | main: a = 5       |
                        |       b = true    |
fn square(n: i32) ...   +-------------------+
Each function call gets its own frame on top of the stack.

The heap

Some data has a size that is not known in advance or that changes: a name typed by a user, a list of orders that grows. Such data goes on the heap, a large, less organised area. Asking for heap space is called allocating. The program finds a free spot big enough, marks it as used, and gets back its address. That address is called a pointer: a number that says where the data is. The pointer itself has a fixed size, so it can sit on the stack.

output
let name = String::from("Priya");

   STACK                         HEAP
  +-----------------+          +---+---+---+---+---+
  | name            |          | P | r | i | y | a |
  |   ptr  ---------+--------> +---+---+---+---+---+
  |   len      = 5  |
  |   capacity = 5  |
  +-----------------+
A String is three numbers on the stack (pointer, length, capacity) plus its bytes on the heap.

Length is how many bytes the text uses now. Capacity is how many bytes were reserved, so it can grow without moving at once.

Think of it like this: The stack is like the plates on your dining table during one meal: put down, used, cleared, all in order. The heap is like a big godown (warehouse). You rent a space, you get a slip with its address, and someone must return that space exactly once when the goods are no longer needed.

The hard part: freeing heap memory

Stack memory cleans itself up when a function ends. Heap memory does not: someone has to free it. Getting this wrong causes four famous bugs:

BugWhat happensResult
Memory leakMemory is never freedThe program slowly uses more and more RAM
Double freeThe same memory is freed twiceCrashes or memory corruption
Use after freeMemory is used after it was freedWrong data, crashes, security holes
Dangling pointerA pointer to memory that is goneLeads to use after free

Large studies by Microsoft and by Google's Chrome team have reported that about 70 percent of their serious security bugs were memory-safety bugs like these. That is why memory safety matters so much.

Three ways languages handle it

  • Manual (C, C++): you call free yourself. Fast, but every mistake above is possible.
  • Garbage collection (Java, Python, Go, JavaScript): a runtime helper finds unused memory and frees it. Safe, but it costs memory and CPU, and can pause the program.
  • Ownership (Rust): the compiler knows exactly when each heap value stops being used and inserts the free there. Safe and fast, at the cost of learning the rules.

Common misunderstandings

  • "The heap is slow, so avoid it." Heap memory is fine; allocating very often is what costs time. Strings and Vecs are used everywhere.
  • "Pointers are scary." In safe Rust you never handle raw addresses; references and smart pointers do it safely.
  • "Stack values are copied, heap values are shared." Not quite: you will see that Rust moves heap values to a new owner instead of sharing them.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Memory 101: the stack and the heap · 1/6

Stack Heap

To understand Rust you need a simple picture of memory. A running program uses two areas: the stack and the heap.

Prefer a video by a teacher? Find free videos on “stack vs heap memory explained rust ownership” on YouTube ↗

In real life: A server that must run for months

A ticket-booking service like IRCTC must run for weeks without restarting. A small memory leak of a few kilobytes per booking adds up to gigabytes after millions of bookings, and the server crashes during a Tatkal rush. In C++ such a leak is easy to write by accident. In Rust, heap memory is freed automatically when its owner goes out of scope, so this whole class of slow-growing leaks is much less likely.

Practice (0/2 done)

Task 1 · Question

Which value lives entirely on the stack?

Task 2 · Practice

Draw (on paper or in a text file) the stack and heap for: let city = String::from("Kochi"); let pin: u32 = 682001; Label the pointer, length and capacity.

Quick quiz

Question 1

1.What must be true of data stored on the stack?

Question 2

2.What is a pointer?

Question 3

3.What is a "double free"?

Question 4

4.For String::from("Priya"), what is on the stack?

Question 5

5.How does Rust decide when to free heap memory?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What must be true of data stored on the stack?

Answer: Its size must be known at compile time

Stack frames have fixed layouts, so sizes must be known in advance.

What is a pointer?

Answer: A value holding the address of other data

A pointer stores where data lives in memory.

What is a "double free"?

Answer: Freeing the same memory twice

Freeing memory twice can corrupt memory and crash the program.

For String::from("Priya"), what is on the stack?

Answer: A pointer, a length and a capacity

The fixed-size part (ptr, len, capacity) is on the stack; the bytes are on the heap.

How does Rust decide when to free heap memory?

Answer: Ownership rules let the compiler insert the free at the right point

Rust frees a value when its owner goes out of scope, decided at compile time.

Who frees heap memory in C?Related

Answer: The program, by calling free

There is no garbage collector.

From Stack and heap

Which memory is cleaned up automatically when a function returns?Related

Answer: The function's local variables on the stack

Stack variables are destroyed at the end of their scope; heap memory stays until deleted.

From Pointers, the stack and the heap

How does Rust free memory?Related

Answer: Through ownership: a value is freed when its owner goes out of scope

Ownership rules make freeing automatic and predictable, and the compiler checks them.

From What Rust is and why learn it

Which is NOT a heap bug?Related

Answer: Integer division by zero

That is an arithmetic error, not a heap bug.

From Memory leaks and other heap bugs

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Ownership: Rust's big idea” before its exam: The ownership rules and moves, Copy and Clone, Ownership and functions.
  2. Module 3 exam: Ownership · 12 questions · 20 min, without help. 4 topics of this module still to finish first.
  3. Then the next module, Borrowing, slices and lifetimes. 50 topics left in the course before the final exam.

← Previous: Mini project: reading input from the user