Stack Memory & Heap Memory

Like for most programming languages, the Rust runtime manages its stored variables, functions, macros and other such pieces of data in two distinct areas of memory: stack memory and heap memory.

Whether a variable is stored in the stack or in the heap depends on its data type, particularly, whether the size of a variable of that data type can be known at compile-time.

Learning this distinction may seem daunting, but understanding it will also further understanding of Rust's ownership system, since memory management is handled with ownership in such a way that most Rust programmers won't need to concern themselves with it, even without a garbage collector.

Stack memory:

Heap memory:

As mentioned on the previous page, C and C++ allow programmers to handle memory manually. More specifically, C allows programmers to manually allocate, reallocate and deallocate spaces on the heap.

Rust, on the other hand, will automatically perform these operations on the heap, depending on the ownership status of a value.

Recall the two string data types mentioned in the last chapter: since String structs are mutable, they are allocated in heap memory, whereas string slices (explained in more detail on the next page) are immutable, and pushed to the stack during execution.

Specifically, String structs are allocated on the heap during their lifetimes, but the actual body of the string is stored on the stack, and the struct has a memory pointer to the first character of the string.


    

When the struct is assigned a new set of characters, these characters are simply pushed onto the stack, and the String struct's pointer is moved to those new characters. The old sequence of characters subsequently goes out of scope, and is eventually popped from the stack.


    

However, in the case of one String struct being assigned to another, the one taking the value will have its pointer moved to the same memory as the struct being assigned. This is to save memory, and prevent bloat on the stack.


    

Values stored exclusively on the stack are known by the compiler to never change in storage size during execution, such as integers, booleans and single characters. However, if these need to be stored in a dynamic context for whatever reason, Rust offers a generic (explained later) called Box.

The Box generic allocates heap memory for a given variable, before pushing a pointer to this memory space onto the stack. A variable is said to be boxed if it is being explicitly stored on the heap using this generic, when it would normally be stored on the stack.