Understanding Shared Ownership in Rust: A Beginner’s Guide 🔍

Yong kang Chia
2 min readAug 29, 2024

--

Smart Pointers in Rust from Rust In Action

Ownership in Rust is hard. But you know what’s even harder than ownership in Rust?

Shared ownership.

But what exactly is shared ownership, and why is it unique to Rust? Let’s break it down.

Ownership

In Rust, ownership ensures that memory is cleaned up when it’s no longer needed, eliminating the need for a garbage collector and keeping Rust blazing fast. Each value in Rust has a single owner; when that owner goes out of scope, the value is automatically dropped.

This unique and effective approach to solving memory management issues gives rise to some critical vulnerabilities for lower-level language i.e Buffer Overflows, Data races.

Basically it's safe and it's blazing fast ⏩

Shared Ownership

But what if multiple parts of your program need to own the same data simultaneously? That’s where shared ownership comes into play!

Shared ownership in Rust is made possible by smart pointers, specifically Rc<T> (Reference Counted) for single-threaded scenarios and Arc<T> (Atomic Reference Counted) for multi-threaded contexts. These smart pointers allow multiple parts of a program to share ownership of the same data while maintaining Rust’s memory and concurrency safety guarantees.

Here’s a quick example:

use std::rc::Rc;
fn main() {
let s = Rc::new(String::from("hello"));
let s1 = Rc::clone(&s);
let s2 = Rc::clone(&s);
println!("s: {}, s1: {}, s2: {}", s, s1, s2);
println!("Reference count: {}", Rc::strong_count(&s));
}

In this code, s, s1, and s2 all share ownership of the same `String`. The reference count increases with each clone and ensures the data is only cleaned up when no owners remain.

For multi-threaded scenarios, Arc<T> works similarly but adds thread safety:

use std::sync::Arc;
use std::thread;
fn main() {
let s = Arc::new(String::from("hello"));
let s1 = Arc::clone(&s);
let s2 = Arc::clone(&s);
let handle1 = thread::spawn(move || {
println!("s1: {}", s1);
});
let handle2 = thread::spawn(move || {
println!("s2: {}", s2);
});
handle1.join().unwrap();
handle2.join().unwrap();
}

With Arc<T>, you can safely share ownership of data across threads, leveraging Rust’s zero-cost abstractions for efficient concurrency.

TLDR

Shared ownership in Rust lets multiple parts of your program share data ownership safely and efficiently, without the need for a garbage collector. It’s one of the many features that make Rust unique and powerful! 🚀

--

--

Yong kang Chia
Yong kang Chia

Written by Yong kang Chia

Blockchain Developer. Chainlink Ex Spartan Group, Ex Netherminds