codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🦀

Rust

30 / 58 topics
29Memory Management30Smart Pointers31Unsafe Rust
Tutorials/Rust/Smart Pointers
🦀Rust

Smart Pointers

Updated 2026-05-15
10 min read

Smart Pointers

Introduction

In Rust, managing memory is a critical aspect of writing safe and efficient programs. Unlike languages with garbage collection, Rust provides explicit control over memory management through ownership, borrowing, and lifetimes. However, sometimes manual memory management can be cumbersome, especially when dealing with complex data structures or shared ownership.

Smart pointers are a powerful feature in Rust that help manage memory more efficiently while maintaining the language's safety guarantees. They provide a way to own heap-allocated values and automatically handle deallocation when they go out of scope. In this tutorial, we'll explore three commonly used smart pointers: Box, Rc, and Arc.

Concept

Box

Box<T> is the simplest form of smart pointer in Rust. It allows you to store data on the heap rather than the stack. The main advantage of using a Box is that it provides ownership semantics, meaning when a Box goes out of scope, its memory is automatically deallocated.

Syntax

let b = Box::new(5);

In this example, b is a Box containing the integer 5. The value 5 is stored on the heap, and b holds a pointer to it.

Rc (Reference Counting)

Rc<T> stands for "reference counting." It allows multiple parts of your program to own a value. This is particularly useful when you have data that needs to be shared between different parts of your code without taking ownership away from the original owner.

Syntax

use std::rc::Rc;

let a = Rc::new(5);
let b = Rc::clone(&a); // Increments the reference count

In this example, both a and b own the integer 5. The reference count is incremented when b is created by cloning a.

Arc (Atomic Reference Counting)

Arc<T> stands for "atomic reference counting." It works similarly to Rc, but it is safe to use in concurrent contexts. This means you can share ownership of a value across multiple threads.

Syntax

use std::sync::Arc;
use std::thread;

let a = Arc::new(5);
let b = Arc::clone(&a);

let handle = thread::spawn(move || {
    println!("Value in the thread: {}", b);
});

handle.join().unwrap();

In this example, both a and b own the integer 5, and b is safely shared across a new thread.

Examples

Using Box

Let's start with a simple example using Box.

fn main() {
    let b = Box::new(5);
    println!("The value inside the box is: {}", b);
}

<OutputBlock>
{`The value inside the box is: 5`}
</OutputBlock>

In this code, we create a `Box` containing the integer `5` and print its value.

### Using Rc

Now, let's see how to use `Rc`.

```rust
use std::rc::Rc;

fn main() {
    let a = Rc::new(5);
    let b = Rc::clone(&a);

    println!("Value in a: {}", a);
    println!("Value in b: {}", b);
    println!("Reference count of a: {}", Rc::strong_count(&a));
}

<OutputBlock>
{`Value in a: 5
Value in b: 5
Reference count of a: 2`}
</OutputBlock>

Here, we create an `Rc` containing the integer `5` and clone it to create another owner `b`. We also print the reference count to see how many owners there are.

### Using Arc

Finally, let's look at an example using `Arc`.

```rust
use std::sync::Arc;
use std::thread;

fn main() {
    let a = Arc::new(5);
    let b = Arc::clone(&a);

    let handle = thread::spawn(move || {
        println!("Value in the thread: {}", b);
    });

    println!("Value in the main thread: {}", a);
    handle.join().unwrap();
}

<OutputBlock>
{`Value in the main thread: 5
Value in the thread: 5`}
</OutputBlock>

In this example, we create an `Arc` containing the integer `5`, clone it to share ownership with a new thread, and print the value from both the main thread and the spawned thread.

## What's Next?

Now that you have a good understanding of smart pointers in Rust, you might be interested in exploring more advanced topics such as unsafe Rust. Unsafe Rust allows you to bypass some of Rust's safety checks, providing more control over memory management but requiring careful handling to avoid undefined behavior.

Stay tuned for more tutorials on Rust and other programming languages!

PreviousMemory ManagementNext Unsafe Rust

Recommended Gear

Memory ManagementUnsafe Rust