{
    "slug": "rust_box_smart_pointers",
    "term": "Rust Smart Pointers (Box, Rc, Arc, RefCell)",
    "category": "rust",
    "difficulty": "intermediate",
    "short": "Smart pointers wrap heap allocations with ownership semantics: Box owns one value, Rc/Arc share ownership, and RefCell adds runtime-checked interior mutability.",
    "long": "A smart pointer is a struct that behaves like a reference but carries extra ownership and management logic, usually implementing `Deref` so you can use it like the value it points to and `Drop` so cleanup happens automatically. Rust's standard library gives you four foundational smart pointers, and knowing when each applies is central to writing idiomatic Rust beyond the borrow checker basics.\n\n`Box<T>` is the simplest: it heap-allocates a single value and gives you sole ownership of it. You reach for it when a value's size is not known at compile time (recursive types like a linked list or tree need indirection through a Box to have a finite size), when you want to move a large value without copying its bytes, or when you need a trait object such as `Box<dyn Error>`. A Box is a single owner, just like a plain stack value, so it follows ordinary move semantics.\n\n`Rc<T>` (reference counted) lets multiple owners share the same heap value. Each `clone` bumps a counter instead of copying the data, and the value is dropped only when the last Rc goes away. Rc is for single-threaded graphs where ownership is genuinely shared - the classic case is a node referenced by several parents. Rc gives you shared, immutable access; it is not thread-safe because its counter is not atomic.\n\n`Arc<T>` (atomically reference counted) is the thread-safe sibling of Rc. It uses atomic operations on the count so it can be sent across threads, at a small performance cost. Use Arc whenever shared ownership crosses a thread boundary, typically paired with a Mutex or RwLock for shared mutation.\n\n`RefCell<T>` provides interior mutability: it lets you mutate data through a shared reference by moving the borrow rules from compile time to runtime. `borrow` and `borrow_mut` hand out guards and panic if you violate the aliasing rule (many readers or one writer) while running. It is single-threaded; the thread-safe analog is Mutex. The common combination `Rc<RefCell<T>>` gives you shared, mutable, single-threaded state - powerful but easy to misuse, since RefCell turns borrow violations into runtime panics rather than compile errors.",
    "aliases": [
        "Box Rc Arc RefCell",
        "rust smart pointers",
        "interior mutability",
        "reference counting"
    ],
    "tags": [
        "rust",
        "smart-pointers",
        "interior-mutability",
        "reference-counting",
        "heap-allocation",
        "ownership"
    ],
    "misconception": "Rc<T> lets you mutate shared data and Arc is just a faster Rc. In reality Rc and Arc give only shared immutable access, you need RefCell or Mutex inside them to mutate, and Arc is slower than Rc because its counter uses atomic operations for thread safety.",
    "why_it_matters": "Choosing the wrong smart pointer leads to compile errors that block sharing, RefCell panics that crash at runtime instead of being caught by the compiler, or needless atomic overhead from using Arc where single-threaded Rc would do.",
    "common_mistakes": [
        "Trying to mutate the value inside an Rc directly, forgetting that Rc gives only shared immutable access and you need an inner RefCell or Mutex.",
        "Using Arc in single-threaded code where Rc is cheaper because it avoids atomic reference-count operations.",
        "Holding two borrow_mut guards (or a borrow and a borrow_mut) on the same RefCell at runtime, causing an 'already borrowed' panic.",
        "Creating reference cycles with Rc<RefCell<T>> that never get dropped, leaking memory because the count never reaches zero.",
        "Reaching for Box<T> when a plain stack value would work, adding an unnecessary heap allocation."
    ],
    "when_to_use": [
        "Boxing a recursive type like a tree or linked list so it has a known finite size, or storing a trait object as Box<dyn Trait>.",
        "Sharing read-only ownership of a value among several owners in single-threaded code with Rc.",
        "Sharing ownership across thread boundaries with Arc, usually combined with Mutex or RwLock for mutation.",
        "Mutating data behind a shared reference where the borrow rules cannot be proven at compile time, using RefCell for runtime-checked interior mutability."
    ],
    "avoid_when": [
        "A plain stack value or reference already satisfies the borrow checker, where adding Box or Rc just introduces an allocation or runtime overhead.",
        "You need shared mutation across threads, where Rc<RefCell<T>> will not compile and you must use Arc<Mutex<T>> instead.",
        "Your data forms cycles that Rc cannot drop, where you need Weak references or a different ownership design to avoid leaks.",
        "Compile-time borrow checking already expresses the access pattern, so RefCell would only move safety checks to a runtime panic for no benefit."
    ],
    "related": [
        "rust_ownership_borrowing",
        "rust_traits",
        "rust_lifetime_annotations"
    ],
    "prerequisites": [
        "rust_ownership_borrowing"
    ],
    "refs": [
        "https://doc.rust-lang.org/book/ch15-00-smart-pointers.html",
        "https://doc.rust-lang.org/std/boxed/struct.Box.html",
        "https://doc.rust-lang.org/std/rc/struct.Rc.html",
        "https://doc.rust-lang.org/std/cell/struct.RefCell.html"
    ],
    "bad_code": "use std::rc::Rc;\n\n#[derive(Debug)]\nstruct Counter {\n    value: i32,\n}\n\nfn main() {\n    let shared = Rc::new(Counter { value: 0 });\n    let other = Rc::clone(&shared);\n\n    // Error: cannot mutate through an Rc - it gives shared, immutable access.\n    // shared.value += 1;\n\n    // Reaching for Arc here is needless: this is all single-threaded,\n    // so the atomic counter just adds overhead.\n    // let shared = std::sync::Arc::new(Counter { value: 0 });\n\n    println!(\"{:?} {:?}\", shared, other);\n}",
    "good_code": "use std::cell::RefCell;\nuse std::rc::Rc;\n\n#[derive(Debug)]\nstruct Counter {\n    value: i32,\n}\n\nfn main() {\n    // Rc shares ownership; RefCell adds runtime-checked interior mutability.\n    let shared = Rc::new(RefCell::new(Counter { value: 0 }));\n    let other = Rc::clone(&shared);\n\n    // Mutate through the shared reference via borrow_mut.\n    shared.borrow_mut().value += 1;\n    other.borrow_mut().value += 1;\n\n    // Read access via borrow; the guard is dropped at the end of the statement.\n    println!(\"value is {}\", shared.borrow().value); // prints 2\n}",
    "quick_fix": "Pick by need: Box for single heap ownership, Rc for shared single-threaded ownership, Arc for shared cross-thread ownership, and wrap in RefCell (or Mutex for threads) when you need to mutate shared data.",
    "severity": "medium",
    "effort": "medium",
    "created": "2026-06-09",
    "updated": "2026-06-09",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/rust_box_smart_pointers",
        "html_url": "https://codeclaritylab.com/glossary/rust_box_smart_pointers",
        "json_url": "https://codeclaritylab.com/glossary/rust_box_smart_pointers.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Rust Smart Pointers (Box, Rc, Arc, RefCell)](https://codeclaritylab.com/glossary/rust_box_smart_pointers) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/rust_box_smart_pointers"
            }
        }
    }
}