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

🧠 Test Your Knowledge

Which smart pointer is best for single ownership on the heap?