Rust Smart Pointers
Advanced memory management with intelligent pointers
🧠What are Smart Pointers?
Smart pointers are data structures that act like pointers but provide additional metadata and capabilities. They help manage memory automatically and enable advanced ownership patterns in Rust programming.
// Basic smart pointer example
use std::rc::Rc;
let data = Rc::new(String::from("Hello, Smart Pointers!"));
let reference1 = Rc::clone(&data);
let reference2 = Rc::clone(&data);
Types of Smart Pointers
Box<T>
Heap allocation for single ownership
let boxed = Box::new(42);
println!("{}", boxed);
Rc<T>
Reference counting for multiple ownership
let rc = Rc::new(vec![1, 2, 3]);
let rc2 = Rc::clone(&rc);
RefCell<T>
Interior mutability with runtime checks
let cell = RefCell::new(5);
*cell.borrow_mut() = 10;
Arc<T>
Atomic reference counting for threads
let arc = Arc::new(42);
let arc2 = Arc::clone(&arc);
🔹 Box<T> - Heap Allocation
Box stores data on the heap and provides a pointer to it:
fn main() {
// Store a large array on the heap
let large_data = Box::new([0; 1000]);
// Recursive type example
enum List {
Cons(i32, Box<List>),
Nil,
}
let list = List::Cons(1,
Box::new(List::Cons(2,
Box::new(List::Nil))));
println!("Boxed value: {}", large_data[0]);
}
Output:
Boxed value: 0
🔹 Rc<T> - Reference Counting
Rc allows multiple owners of the same data:
use std::rc::Rc;
fn main() {
let data = Rc::new(String::from("Shared data"));
let owner1 = Rc::clone(&data);
let owner2 = Rc::clone(&data);
println!("Reference count: {}", Rc::strong_count(&data));
println!("Data: {}", owner1);
println!("Same data: {}", owner2);
}
Output:
Reference count: 3
Data: Shared data
Same data: Shared data
🔹 RefCell<T> - Interior Mutability
RefCell allows mutation even when immutable references exist:
use std::cell::RefCell;
fn main() {
let data = RefCell::new(vec![1, 2, 3]);
// Borrow mutably and modify
data.borrow_mut().push(4);
// Borrow immutably and read
println!("Vector: {:?}", *data.borrow());
// Combined with Rc for shared mutable data
let shared = Rc::new(RefCell::new(5));
let shared_clone = Rc::clone(&shared);
*shared.borrow_mut() += 1;
println!("Shared value: {}", *shared_clone.borrow());
}
Output:
Vector: [1, 2, 3, 4]
Shared value: 6