Ownership & Move Semantics
Ownership is Rust's most unique feature. It enables memory safety without a garbage collector by managing heap resources using strict scope rules.
1 Ownership Rules & Move Semantics
Memory allocations are managed using three core rules:
- Each value in Rust has an owner variable.
- There can only be one owner at a time.
- When the owner goes out of scope, the value is automatically dropped/deallocated.
Move Semantics: When assigning a heap-allocated variable (like a String) to another variable, ownership of the value is **moved** to the new variable. The original variable becomes invalid immediately, preventing double-free memory bugs.
2 Ownership Move Code
Let's run a program demonstrating ownership moves and heap drops:
Rust — Ownership Move
▶ Run Code
fn main() {
// Allocating a String on the heap
let s1 = String::from("hello");
// Ownership of the heap data is moved to s2
let s2 = s1;
// println!("s1: {}", s1); // This line would cause a compile-time error! s1 is invalid now.
println!("s2: {}", s2); // s2 is the valid owner
// Deep copy (clone) can be used to copy heap memory explicitly
let s3 = s2.clone();
println!("s2: {}, s3: {}", s2, s3);
}
3 Code Challenge
Challenge: Write a function that accepts a `String` variable, which moves ownership into the function. Try to access the variable in `main()` after calling the function, observe the compile-time error, and then fix it by passing a cloned copy instead.