Course contentsShow
← Rust
Lesson 999 of 1,9109. Smart Pointers and Interior MutabilityFree lesson

Reference Counting Mechanism

Implement shared ownership for read-only data across multiple contexts.

In this lesson, you will learn how to use the Rc<T> smart pointer to enable shared ownership of data when multiple parts of your program need to read the same heap-allocated value.

The Problem with Single Ownership

Up to this point, you have worked extensively with Box<T>, which enforces a strict single-owner model. If you have a large data structure—such as a complex configuration graph or a shared look-up table—that needs to be accessed by different components, Box<T> fails you. You cannot "move" the data into multiple owners, and you cannot safely share mutable references without violating Rust’s aliasing rules.

Introducing Rc<T>

Rc<T> stands for Reference Counted. It allows multiple parts of your program to own the same piece of data on the heap. Internally, the Rc<T> keeps track of the number of references to that data.

Whenever you clone an Rc, you aren't cloning the data itself; you are creating a new pointer that increments a hidden counter. When a pointer goes out of scope, the counter decrements. Only when the count hits zero is the heap memory finally deallocated.

use std::rc::Rc;

fn main() {
    // The data is allocated on the heap
    let shared_data = Rc::new(vec![1, 2, 3]);

    // Create a new reference (pointer incremented)
    let reference_a = Rc::clone(&shared_data);
    let reference_b = Rc::clone(&shared_data);

    println!("Data: {:?}", reference_a);
    println!("Count: {}", Rc::strong_count(&shared_data));
}

Constraints of Reference Counting

The most important rule to remember is that Rc<T> is strictly for read-only data. Because the data is shared by many owners, allowing one owner to mutate the data would break the safety guarantees of Rust’s borrow checker. If you try to change the contents of an Rc, the compiler will prevent it. If you find yourself needing to modify shared state later, you will eventually pair Rc with interior mutability primitives, but for now, treat Rc as a way to safely share immutable state across different execution contexts.

Key Takeaway: Rc<T> enables multiple ownership by maintaining a reference count, allowing heap-allocated data to persist until the final owner goes out of scope.