Smart Pointers¶
Smart pointers are data structures that act like pointers but have additional metadata and capabilities. They implement Deref (for transparent dereferencing) and Drop (for automatic cleanup). The main smart pointers are Box<T>, Rc<T>, Arc<T>, RefCell<T>, and Cow<T>.
Key Facts¶
- Box
= heap allocation with single ownership, zero-cost abstraction (just a pointer) - Rc
= reference counting, multiple owners, single-threaded only - Arc
= atomic reference counting, multiple owners, thread-safe - RefCell
= interior mutability with runtime borrow checking - Cow
= clone-on-write, avoids allocation when data doesn't need modification Box<T>is the most common - used for recursive types, trait objects, and large stack-to-heap moves
Patterns¶
Box - Heap Allocation¶
// Recursive type (requires known size)
enum List {
Cons(i32, Box<List>),
Nil,
}
// Trait objects
let animal: Box<dyn Animal> = Box::new(Dog { name: "Rex".into() });
// Large data on heap
let big_array = Box::new([0u8; 1_000_000]);
Rc - Reference Counting¶
use std::rc::Rc;
let a = Rc::new(vec![1, 2, 3]);
let b = Rc::clone(&a); // increment reference count (cheap)
let c = Rc::clone(&a);
println!("References: {}", Rc::strong_count(&a)); // 3
// Data dropped when last Rc goes out of scope
RefCell - Interior Mutability¶
use std::cell::RefCell;
let data = RefCell::new(vec![1, 2, 3]);
// Runtime borrow checking
let borrowed = data.borrow(); // immutable borrow
// data.borrow_mut(); // PANIC: already borrowed immutably
drop(borrowed);
data.borrow_mut().push(4); // OK: no active borrows
Common Combinations¶
// Multiple owners with mutability (single-threaded)
let shared = Rc::new(RefCell::new(HashMap::new()));
// Multiple owners with mutability (multi-threaded)
let shared = Arc::new(Mutex::new(HashMap::new()));
Gotchas¶
Rc<T>can create reference cycles → memory leaks; useWeak<T>to break cyclesRefCell<T>panics at runtime if borrow rules violated - compile-time safety traded for flexibilityRc<T>is NOT thread-safe (useArc<T>for multithreading)Box<T>moves data to heap but the Box itself lives on stack (pointer-sized)
See Also¶
- ownership and move semantics - ownership model that smart pointers extend
- concurrency - Arc + Mutex for thread-safe shared state
- traits - Deref and Drop traits that power smart pointers