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.comIn 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.
