Advanced

Advanced Ownership

Master lifetimes, Rc, and smart pointers.

What you will see

COMPILE_ERROR

About 2 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

You will share values with Rc, put data on the heap with Box, and check borrows with lifetimes.

1

I share a value with two Rc handles. Dropping one does not free the value until the last Rc is dropped.

use std::rc::Rc; fn main() { let a = Rc::new(5); let b = Rc::clone(&a); println!("{} {}", a, b); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
5 5
2

I put a value on the heap with Box and dereference it to read it. Box has a known size while the data lives on the heap.

fn main() { let boxed = Box::new(42); println!("{}", *boxed); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
42
3

I write a function that returns the longer of two string slices using a lifetime. The returned reference lives as long as both inputs.

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } } fn main() { println!("{}", longest("hi", "there")); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
there
4

I create two immutable borrows of the same value. Many immutable borrows can exist at the same time.

fn main() { let s = String::from("hi"); let r1 = &s; let r2 = &s; println!("{} {}", r1, r2); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
hi hi
5

I try to borrow mutably while an immutable borrow is still alive. The compiler rejects it, showing Rust allows only one mutable borrow at a time.

fn main() { let mut s = String::from("hi"); let r1 = &s; let r2 = &mut s; println!("{} {}", r1, r2); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
COMPILE_ERROR
You cannot borrow mutably while an immutable borrow is still active.

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

Ownership can be shared via counting or verified via lifetimes.
1 Create a value on the heap
↓
2 Share ownership with Rc or Arc
↓
3 Or borrow with a lifetime-checked reference
↓
4 Free when the last owner drops
Why this works
Lifetime annotations

Lifetimes name how long references live:

fn first<'a>(s: &'a str) -> &'a str {
    &s[0..1]
}

The compiler checks that references never dangle. If a borrow could be invalid, compilation fails.

Why it works: this is what makes Rust safe without a garbage collector.

Smart pointers

Smart pointers own their data:

TypeBehavior
Box<T>heap ownership
Rc<T>reference counting
Arc<T>atomic counting (safe across threads)
RefCell<T>interior mutability

Each trades off safety and control. Box is the simplest and most common.

Examples

Rc for shared ownership

Reference counting

use std::rc::Rc;

let a = Rc::new(5);
let b = Rc::clone(&a);   // both own the value
// dropping a does not free b

Rc<T> lets multiple owners share a value. The value lives until the last Rc is dropped.

Why it works: Rc counts references and frees memory when the count hits zero.

Lifetimes

Borrow checking

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

'a is a lifetime parameter. It promises the returned reference lives as long as the inputs. Lifetimes let Rust verify borrows are valid.

Why it works: the compiler rejects any borrow that could outlive its data.

Box for heap data

Heap allocation

let boxed = Box::new(42);
println!("{}", *boxed);   // dereference

Box<T> puts a value on the heap and gives a pointer to it. Use it for large data or recursive types.

Why it works: Box has a known size (a pointer) while the data lives on the heap.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Traits
Previous Lesson
Traits
Next Lesson
Error Handling
Error Handling →