Rc<T> / Arc<T>
Rc<T> and Arc<T> are reference-counted smart pointers that allow a single value to have multiple owners. Rc is for single-threaded use, while Arc is the thread-safe version.
Syntax
use std::rc::Rc; use std::sync::Arc; // Rc: creates multiple owners in a single-threaded context. let a = Rc::new(value); let b = Rc::clone(&a); // Increments the reference count. // Arc: creates multiple owners across threads. let a = Arc::new(value); let b = Arc::clone(&a); // Can be shared across threads. // Check the reference count Rc::strong_count(&a) Arc::strong_count(&a)
Method List
| Method | Description |
|---|---|
| Rc::new(v) | Wraps the value v in an Rc. The reference count starts at 1. |
| Rc::clone(&a) | Creates a new Rc pointer, incrementing the reference count. |
| Rc::strong_count(&a) | Returns the current strong reference count. |
| Rc::weak_count(&a) | Returns the current weak reference count (for Weak references). |
| Arc::new(v) | Wraps the value v in an Arc, allowing safe sharing across threads. |
| Arc::clone(&a) | Creates a new Arc pointer, atomically incrementing the reference count. |
Sample Code
use std::rc::Rc;
use std::sync::Arc;
use std::thread;
fn main() {
// Rc: multiple owners in a single-threaded context.
let rc_val = Rc::new(String::from("shared"));
let rc_a = Rc::clone(&rc_val);
let rc_b = Rc::clone(&rc_val);
println!("{}", rc_val); // shared
println!("{}", rc_a); // shared
println!("count: {}", Rc::strong_count(&rc_val)); // count: 3
drop(rc_a);
println!("after drop: {}", Rc::strong_count(&rc_val)); // after drop: 2
// Arc: shared across threads.
let arc_val = Arc::new(42);
let handles: Vec<_> = (0..3).map(|i| {
let val = Arc::clone(&arc_val);
thread::spawn(move || {
println!("thread {}: {}", i, val);
})
}).collect();
for h in handles {
h.join().unwrap();
}
}
Output
shared shared count: 3 after drop: 2 thread 0: 42 thread 1: 42 thread 2: 42
Notes
In Rust's ownership system, a value normally has exactly one owner. Using Rc<T> or Arc<T> allows multiple owners. When all references are dropped (the count reaches zero), the memory is automatically freed.
Rc cannot be shared across threads because it does not implement the Send trait. Always use Arc when sharing data between threads.
Circular references with Rc will cause memory leaks. If there is a risk of a cycle, make one side a Weak<T> (weak reference) to prevent the reference count from cycling.
If you find any errors or copyright issues, please contact us.