Ownership & Move Semantics

🦀 Rust Lesson 4 Intermediate

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.