Rust

Ownership (Rust)

Ownership is Rust’s compile-time memory management strategy: the compiler tracks which variable owns each value and inserts the drop (deallocation) automatically when the owner goes out of scope.

Why ownership?

C/C++ rely on the programmer to free memory correctly. Garbage-collected languages pay runtime cost and unpredictable pause times. Ownership gives C++-style predictability with compile-time guarantees that no double-free, use-after-free, or leak slips through.

The three rules:

  1. Every value has a variable that is its owner
  2. There can be only one owner at a time
  3. When the owner goes out of scope, the value is dropped

Move semantics

let s1 = String::from("hello");
let s2 = s1;            // ownership moves to s2
println!("{}", s1);     // compile error: s1 was moved

If both s1 and s2 pointed at the same heap buffer, dropping both would double-free. Rust forbids that statically by invalidating s1.

Copy vs Move

Simple types (integers, bools, floats) implement the Copy trait and use copy semantics, since copies are cheap and moves would be cumbersome. Heap-backed types like String and Vec<T> move by default. .clone() is the explicit opt-in for a deep copy.

Passing a value to a function and returning it follow the same rules: arguments are moved (or copied) in, return values move out.

C++ RAII has one owner too, but the C++ compiler doesn’t enforce it, so you can still write code that breaks the invariant and segfaults.

What ownership prevents

  • Memory leak, owner going out of scope always drops
  • Double-free, one owner means one drop
  • Use-after-free, a moved value can’t be referenced
  • Reading uninitialized memory, caught by the compiler
  • Stack value escaping its scope, compiler forces a move or copy