Ownership transfer prevents double-free and use-after-free

Marcus Chen Jan 2026
1 tab
fn take_ownership(s: String) {
    println!("Took ownership: {}", s);
} // s is dropped here

fn main() {
    let message = String::from("hello");
    take_ownership(message);
    // println!("{}", message); // ❌ compile error: value moved
}
1 file · rust Explain with highlit

Rust's ownership system guarantees memory safety without garbage collection. Each value has exactly one owner, and when ownership is transferred (moved), the previous owner can't use it anymore. This prevents double-frees and use-after-free bugs at compile time. The pattern below shows a String being moved into a function; after the call, the original binding is invalid. The compiler enforces this. For expensive operations like building large data structures, I design APIs to take ownership when the caller won't need the value again, avoiding unnecessary clones. This zero-cost abstraction is the foundation of Rust's safety guarantees, and once you internalize it, you stop fighting the borrow checker and start designing better APIs.