Rust Stack and Heap
In Rust, variables can be allocated on either the stack or the heap, depending on how they're declared.
The stack is a region of memory that is used to store variables that have a fixed size and lifetime. When you declare a variable on the stack, Rust automatically manages its lifetime for you, and the variable is automatically deallocated when it goes out of scope.
Here's an example of a variable allocated on the stack:
fn main() { let x = 5; // variable x is allocated on the stack println!("x: {}", x); } // x is automatically deallocated when the function exitsSource:www.theitroad.com
In this example, we're declaring a variable x
with a value of 5
inside the main
function. Since x
has a fixed size and lifetime, Rust allocates it on the stack. When the function exits, Rust automatically deallocates x
, because its lifetime has ended.
The heap is a region of memory that is used to store variables that have a dynamic size or lifetime. When you allocate a variable on the heap, you're responsible for managing its lifetime and deallocating it when you're done with it.
Here's an example of a variable allocated on the heap:
fn main() { let mut s = String::from("hello"); // variable s is allocated on the heap s.push_str(", world!"); // modify the value of s println!("{}", s); // prints "hello, world!" // s is automatically deallocated when it goes out of scope, but we can also deallocate it manually using the drop function: drop(s); // deallocates the memory used by s }
In this example, we're declaring a variable s
using the String::from
constructor, which allocates a string on the heap. We're then modifying the value of s
by appending ", world!" to it using the push_str
method. Finally, we're printing the value of s
and manually deallocating it using the drop
function.
It's important to note that Rust's ownership model ensures that heap-allocated variables are always properly managed and deallocated, which helps prevent common bugs like memory leaks and use-after-free errors. Rust's borrow checker enforces strict rules for ownership and borrowing, which help prevent data races and other concurrency bugs as well.