Memory indirection primitives for recursive data structures, single-threaded shared ownership, and atomic thread-safe reference counting.
use std::sync::Arc;
use std::thread;
fn main() {
// Arc allows multi-threaded shared ownership
let shared_state = Arc::new(vec![10, 20, 30]);
let mut handles = vec![];
for thread_id in 0..3 {
let state_clone = Arc::clone(&shared_state); // Bumps atomic strong count
handles.push(thread::spawn(move || {
println!("Thread {}: len = {}", thread_id, state_clone.len());
}));
}
for h in handles { h.join().unwrap(); }
println!("Strong count: {}", Arc::strong_count(&shared_state));
}Smart pointers are data structures that act like pointers while offering metadata and capabilities like automatic resource management via the `Deref` and `Drop` traits.
`Box<T>` puts data on the heap. It is essential for recursive types whose size cannot be calculated at compile time, such as linked lists and AST tree nodes.
`Rc<T>` (Reference Counted) tracks the number of owners of a heap value. When a clone is made, the strong count increments; when an instance goes out of scope, it decrements. When it hits 0, the memory is freed.
`Arc<T>` (Atomic Reference Counted) performs atomic increments and decrements, making it safe to send across threads at the cost of atomic synchronization instructions.
An `Rc<T>` pointer on the stack points to a heap header containing: `[ strong_count: usize | weak_count: usize | value: T ]`.
// Stack Heap
// ptr: 0x5000 ──────► [ strong: 2 | weak: 1 | data: "Payload" ]