In Rust, there is no traditional garbage collector, so smart pointers are used to manage ownership of complex structures. The most commonly used are:
Box<T> — allocates memory for an object on the heap and transfers ownership of it. It is used when the size of data is not known at compile time or when a movable but unique resource is required.
Rc<T> (Reference Counted) — reference counting, allows multiple variables to "share" ownership of immutable data (only in a single-threaded context).
Arc<T> (Atomic Reference Counted) — also implements reference counting, but atomic; applicable in multithreaded programs.
RefCell<T> — provides "interior mutability" at runtime, allowing the contents to be changed even through an immutable reference, but only in one thread (not thread-safe!).
Example:
use std::rc::Rc; let a = Rc::new(vec![1,2,3]); let b = Rc::clone(&a); // Now both a and b own the same data
Can Rc<T> be used in multithreaded code if all threads only read data? Explain.
Answer: No, it can't! Even though Rc<T> allows only immutable access to data, the Rc<T> container itself is not thread-safe, as its internal reference count is not protected against data races. This is what Arc<T> is for—its internal counter is thread-safe.
Example:
// The following code will not compile! use std::thread; use std::rc::Rc; let five = Rc::new(5); for _ in 0..10 { let five = Rc::clone(&five); thread::spawn(move || { println!("{}", five); }); }
Story
Story
Story
In a business logic module, they used RefCell<T> to organize mutable access to data that was also passed through Arc<T> between threads. But the attempt to combine RefCell<T> and Arc<T> led to races and panic at runtime. For a thread-safe option, they should have used Mutex<T> or RwLock<T> instead of RefCell<T>.