Bird
Raised Fist0
Rustprogramming~20 mins

Ownership with smart pointers in Rust - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Rust Smart Pointer Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this Rust code using Rc?

Consider the following Rust code using Rc smart pointers. What will be printed?

Rust
use std::rc::Rc;

fn main() {
    let a = Rc::new(5);
    let b = Rc::clone(&a);
    println!("{}", Rc::strong_count(&a));
}
A1
BCompilation error
C2
D0
Attempts:
2 left
💡 Hint

Think about how many owners the Rc pointer has after cloning.

❓ Predict Output
intermediate
2:00remaining
What happens when you try to mutate data inside an Rc without RefCell?

What error or output will this Rust code produce?

Rust
use std::rc::Rc;

fn main() {
    let data = Rc::new(5);
    let mut_ref = Rc::get_mut(&mut Rc::clone(&data));
    match mut_ref {
        Some(v) => *v = 10,
        None => println!("Cannot get mutable reference"),
    }
}
ACannot get mutable reference
BCompilation error due to mutability
CProgram panics at runtime
DValue is changed to 10
Attempts:
2 left
💡 Hint

Rc allows mutation only if there is exactly one owner.

🔧 Debug
advanced
2:00remaining
Why does this code cause a runtime panic with RefCell?

Examine the Rust code below. Why does it panic at runtime?

Rust
use std::cell::RefCell;

fn main() {
    let data = RefCell::new(5);
    let _borrow1 = data.borrow_mut();
    let _borrow2 = data.borrow_mut();
}
ABecause multiple mutable borrows are not allowed simultaneously
BBecause RefCell does not allow any borrows
CBecause the data is immutable
DBecause borrow_mut returns an error that is not handled
Attempts:
2 left
💡 Hint

Think about Rust's borrowing rules enforced at runtime by RefCell.

🧠 Conceptual
advanced
2:00remaining
What is the main difference between Box and Rc in Rust?

Choose the best explanation of the difference between Box and Rc smart pointers.

ABox automatically clones data; Rc does not
BBox allows multiple owners; Rc allows only one owner
CBox is for stack allocation; Rc is for heap allocation
DBox provides single ownership and heap allocation; Rc provides shared ownership with reference counting
Attempts:
2 left
💡 Hint

Think about ownership and how many owners each pointer type supports.

❓ Predict Output
expert
3:00remaining
What is the output of this code mixing Rc and RefCell?

Analyze the following Rust code. What will it print?

Rust
use std::rc::Rc;
use std::cell::RefCell;

fn main() {
    let data = Rc::new(RefCell::new(10));
    let data_clone = Rc::clone(&data);
    *data_clone.borrow_mut() += 5;
    println!("{}", data.borrow());
}
A10
B15
CCompilation error due to borrow rules
DRuntime panic due to multiple mutable borrows
Attempts:
2 left
💡 Hint

Consider how Rc and RefCell work together to allow mutation.

Practice

(1/5)
1. Which smart pointer in Rust allows multiple parts of your program to own the same data safely?
easy
A. RefCell
B. Box
C. Rc
D. Arc

Solution

  1. Step 1: Understand ownership types

    Box provides unique ownership, Rc allows shared ownership in single-threaded contexts, RefCell allows interior mutability, and Arc is for shared ownership across threads.
  2. Step 2: Identify shared ownership in single-threaded code

    Rc is the smart pointer designed for multiple owners in single-threaded programs.
  3. Final Answer:

    Rc -> Option C
  4. Quick Check:

    Shared ownership = Rc [OK]
Hint: Shared ownership in single-threaded Rust uses Rc [OK]
Common Mistakes:
  • Confusing Box with shared ownership
  • Thinking RefCell shares ownership
  • Mixing Arc with single-threaded Rc
2. Which of the following is the correct way to create a Box smart pointer holding the integer 10?
easy
A. let b = Box::new(10);
B. let b = Box(10);
C. let b = new Box(10);
D. let b = Box::create(10);

Solution

  1. Step 1: Recall Box creation syntax

    The correct way to create a Box is using Box::new(value).
  2. Step 2: Check each option

    let b = Box::new(10); uses Box::new(10), which is correct. Options A, C, and D use invalid syntax.
  3. Final Answer:

    let b = Box::new(10); -> Option A
  4. Quick Check:

    Box creation = Box::new(value) [OK]
Hint: Use Box::new(value) to create a Box smart pointer [OK]
Common Mistakes:
  • Using Box(10) instead of Box::new(10)
  • Trying new Box(10) like other languages
  • Using non-existent Box::create method
3. What will be the output of this Rust code?
use std::rc::Rc;

let a = Rc::new(5);
let b = Rc::clone(&a);
println!("{}", Rc::strong_count(&a));
medium
A. 1
B. 2
C. 5
D. Compilation error

Solution

  1. Step 1: Understand Rc cloning

    Cloning an Rc pointer increases the reference count but does not clone the data.
  2. Step 2: Count strong references

    Initially, a has a count of 1. After b = Rc::clone(&a), the count becomes 2.
  3. Final Answer:

    2 -> Option B
  4. Quick Check:

    Rc clone increments count = 2 [OK]
Hint: Rc::clone increases strong_count by 1 [OK]
Common Mistakes:
  • Thinking Rc::clone copies data
  • Expecting count to remain 1
  • Confusing Rc with Box ownership
4. Identify the error in this Rust code using RefCell:
use std::cell::RefCell;

let data = RefCell::new(10);
let r1 = data.borrow_mut();
let r2 = data.borrow_mut();
println!("{} {}", r1, r2);
medium
A. Cannot borrow mutably twice at the same time
B. RefCell cannot hold integers
C. Missing semicolon after borrow_mut()
D. Cannot print RefCell values directly

Solution

  1. Step 1: Understand RefCell borrowing rules

    RefCell allows mutable borrowing at runtime but only one mutable borrow at a time.
  2. Step 2: Analyze the code

    The code tries to create two mutable borrows r1 and r2 simultaneously, which causes a runtime panic.
  3. Final Answer:

    Cannot borrow mutably twice at the same time -> Option A
  4. Quick Check:

    RefCell mutable borrow rule = one at a time [OK]
Hint: Only one mutable borrow allowed with RefCell at once [OK]
Common Mistakes:
  • Thinking RefCell forbids integers
  • Assuming multiple mutable borrows are allowed
  • Confusing compile-time and runtime borrow checks
5. You want to create a tree structure where each node can have multiple children and each child can access its parent. Which combination of smart pointers is best to avoid ownership errors?
hard
A. Use Weak for children and Box for parent references
B. Use Box for both children and parent references
C. Use RefCell for children and Rc for parent references
D. Use Rc for children and Weak for parent references

Solution

  1. Step 1: Understand ownership in tree structures

    Children own their data, so Rc is used for shared ownership of children nodes.
  2. Step 2: Avoid reference cycles

    Parents are referenced by children, but to avoid cycles, parents should be referenced with Weak pointers.
  3. Step 3: Combine smart pointers correctly

    Using Rc for children and Weak for parents prevents memory leaks and ownership errors.
  4. Final Answer:

    Use Rc for children and Weak for parent references -> Option D
  5. Quick Check:

    Tree ownership = Rc children + Weak parents [OK]
Hint: Use Weak for back references to avoid cycles [OK]
Common Mistakes:
  • Using Box for parent causes ownership conflicts
  • Using Rc for parents causes reference cycles
  • Ignoring Weak pointers to break cycles
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard