Smart Pointers (Box, Rc, RefCell)

Rust is a systems programming language focused on speed, memory safety, and fearless concurrency — and smart pointers give you heap allocation, shared ownership, and interior mutability while keeping those guarantees.

Learn Smart Pointers (Box, Rc, RefCell) in our free Rust course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a…

Part of the free Rust course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll meet Box for heap data and recursion, Rc for shared ownership, and RefCell for interior mutability.

What You'll Learn in This Lesson

1️⃣ Box: Heap Allocation and Recursion

Box<T> is the simplest smart pointer: it puts a value on the heap and owns it. You access the value just like a reference thanks to auto-dereferencing. Its standout use is enabling recursive types — without the indirection a Box provides, a type that contains itself would have infinite size.

The Cons list could only be defined because each link's tail is a Box<List> — a fixed-size pointer — rather than another List inline.

2️⃣ Rc and RefCell: Sharing and Interior Mutability

Rc<T> (reference counted) lets several owners share the same data; cloning bumps a count rather than copying. RefCell<T> moves borrow checking to runtime , letting you mutate data through a shared reference. Combined as Rc<RefCell<T>> , you get shared and mutable data.

Both log and log2 pointed at the same vector, so a push through either was visible through both. That's the power — and the responsibility — of shared mutable state.

Your turn. Fill in the blanks marked ___ , then run it.

Combine Rc and RefCell to share and mutate a counter through two handles. Run it with cargo run .

📋 Quick Reference — Smart Pointers

Practice quiz

Where does Box<T> store its value?

  • On the stack
  • In a register
  • On the heap
  • In static memory

Answer: On the heap. Box<T> allocates its value on the heap behind a single owner.

Why is Box needed for a recursive type like a Cons list?

  • Without indirection the type would have infinite size
  • For speed
  • To enable cloning
  • To allow threads

Answer: Without indirection the type would have infinite size. Box gives a fixed-size pointer so the recursive type's size is known.

What does Rc stand for?

  • Raw cell
  • Recursive container
  • Read copy
  • Reference counted

Answer: Reference counted. Rc is a reference-counted smart pointer allowing multiple owners.

What does Rc::clone(&shared) do?

  • Deep-copies the data
  • Increments the reference count
  • Moves ownership
  • Frees the data

Answer: Increments the reference count. Rc::clone bumps the owner count rather than copying the data.

After two Rc::clone calls on a fresh Rc, what is the strong_count?

  • 3
  • 1
  • 2
  • 0

Answer: 3. The original plus two clones gives a strong_count of 3.

What does RefCell<T> provide?

  • Thread safety
  • Compile-time-only checks
  • Interior mutability with runtime borrow checks
  • Heap allocation

Answer: Interior mutability with runtime borrow checks. RefCell allows mutation through a shared reference, checked at runtime.

Is Rc<T> thread-safe?

  • Yes
  • No, it is single-threaded; use Arc across threads
  • Only with RefCell
  • Only on the heap

Answer: No, it is single-threaded; use Arc across threads. Rc is single-threaded; Arc is the thread-safe atomic counterpart.

What does *counter.borrow_mut() += 1 do on a RefCell?

  • Reads the value
  • Clones the cell
  • Panics always
  • Mutably borrows and increments it

Answer: Mutably borrows and increments it. borrow_mut takes a mutable runtime borrow so you can change the value.

What is the classic combo for shared, mutable, single-threaded state?

  • Box<Rc<T>>
  • Rc<RefCell<T>>
  • Arc<Mutex<T>>
  • Vec<Box<T>>

Answer: Rc<RefCell<T>>. Rc<RefCell<T>> gives shared ownership plus interior mutability.

What runtime error happens with two overlapping mutable RefCell borrows?

  • A compile error
  • Silent corruption
  • BorrowMutError panic
  • Nothing

Answer: BorrowMutError panic. RefCell enforces borrow rules at runtime, panicking with BorrowMutError.