← Back to Rust Course | Chapter 13: Smart Pointers & Unsafe | Lesson 2 of 7

Rc और Arc

Rc और Arc एक से ज़्यादा owners को एक जैसी value share करने देते हैं, साफ़ करने से पहले count करते हुए कि कितने अब भी इसे उपयोग कर रहे हैं।
Syntax
rust
let a = Rc::new(value);
let b = Rc::clone(&a);
Rc::strong_count(&a);

let a = Arc::new(value);  // thread-safe

Sharing Data with Rc

Rc::new(value) shared ownership के लिए एक value को wrap करता है; इस पर .clone() call करना उसी data की ओर point करने वाला एक और owner produce करता है और एक internal reference count increment करता है।

उदाहरण: Sharing Data with Rc

markup
// Bring `std::rc::Rc` into scope
use std::rc::Rc;

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `shared`, set to `Rc::new(String::from("shared data"))`
    let shared = Rc::new(String::from("shared data"));
    // Declare an immutable variable `owner_two`, set to `Rc::clone(&shared)`
    let owner_two = Rc::clone(&shared);
    // Print "{} and {}" to the console, substituting in `shared, owner_two` (with a trailing newline)
    println!("{} and {}", shared, owner_two);
    // Print "Reference count: {}" to the console, substituting in `Rc::strong_count(&shared)` (with a trailing newline)
    println!("Reference count: {}", Rc::strong_count(&shared));
}

Rc Clone Is Cheap

किसी Rc को clone करना underlying data को deep-copy नहीं करता -- यह सिर्फ reference count increment करता है, इसे एक बहुत सस्ता operation बनाते हुए चाहे shared data कितना भी बड़ा हो।

उदाहरण: Rc Clone Is Cheap

markup
// Bring `std::rc::Rc` into scope
use std::rc::Rc;

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `data`, set to `Rc::new(vec![1, 2, 3, 4, 5])`
    let data = Rc::new(vec![1, 2, 3, 4, 5]);
    // Declare an immutable variable `clone_a`, set to `Rc::clone(&data)`
    let clone_a = Rc::clone(&data);
    // Declare an immutable variable `clone_b`, set to `Rc::clone(&data)`
    let clone_b = Rc::clone(&data);
    // Print "Count: {}" to the console, substituting in `Rc::strong_count(&data)` (with a trailing newline)
    println!("Count: {}", Rc::strong_count(&data));
    // Print "{:?}" to the console, substituting in `clone_a` (with a trailing newline)
    println!("{:?}", clone_a);
    // Print "{:?}" to the console, substituting in `clone_b` (with a trailing newline)
    println!("{:?}", clone_b);
}

Using Arc for Thread Safety

Arc<T> Rc<T> जैसा behave करता है लेकिन इसके reference count के लिए atomic operations उपयोग करता है, इसे plain Rc के विपरीत कई threads में share करने के लिए सुरक्षित बनाते हुए।

उदाहरण: Using Arc for Thread Safety

markup
// Bring `std::sync::Arc` into scope
use std::sync::Arc;
// Bring `std::thread` into scope
use std::thread;

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `shared`, set to `Arc::new(String::from("shared across threads"))`
    let shared = Arc::new(String::from("shared across threads"));
    // Declare an immutable variable `shared_clone`, set to `Arc::clone(&shared)`
    let shared_clone = Arc::clone(&shared);
    let handle = thread::spawn(move || {
        // Print "From thread: {}" to the console, substituting in `shared_clone` (with a trailing newline)
        println!("From thread: {}", shared_clone);
    });
    handle.join().unwrap();
    // Print "From main: {}" to the console, substituting in `shared` (with a trailing newline)
    println!("From main: {}", shared);
}

Value Dropped When Count Reaches Zero

Rc/Arc से wrapped underlying data तब ही असल में free होता है जब हर owner drop हो चुका हो और reference count zero तक गिर जाए, जो बिना manual bookkeeping के अपने आप होता है।

उदाहरण: Value Dropped When Count Reaches Zero

markup
// Bring `std::rc::Rc` into scope
use std::rc::Rc;

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `a`, set to `Rc::new(10)`
    let a = Rc::new(10);
    // Print "Count after creating a: {}" to the console, substituting in `Rc::strong_count(&a)` (with a trailing newline)
    println!("Count after creating a: {}", Rc::strong_count(&a));
    {
        // Declare an immutable variable `_b`, set to `Rc::clone(&a)`
        let _b = Rc::clone(&a);
        // Print "Count with b alive: {}" to the console, substituting in `Rc::strong_count(&a)` (with a trailing newline)
        println!("Count with b alive: {}", Rc::strong_count(&a));
    }
    // Print "Count after b dropped: {}" to the console, substituting in `Rc::strong_count(&a)` (with a trailing newline)
    println!("Count after b dropped: {}", Rc::strong_count(&a));
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. किसी plain Rc के अंदर data को सीधे mutate करने की कोशिश करना -- Rc अपने आप सिर्फ shared, immutable access allow करता है।
  2. कई threads में Rc उपयोग करना, जब thread safety के लिए Arc (atomic reference counting) ज़रूरी है।
  3. Rc से एक reference cycle बनाना (दो values एक-दूसरे को own करना), जो memory leak करता है क्योंकि count कभी zero नहीं पहुंचता।
चैप्टर सारांश
  • Rc<T> (Reference Counted) एक single thread के अंदर उसी heap-allocated value के कई owners enable करता है।
  • Arc<T> (Atomically Reference Counted) Rc का thread-safe equivalent है, कई threads में usable।
  • किसी Rc/Arc पर .clone() underlying data को deep-copy करने के बजाय reference count बढ़ाता है।
  • Value तब ही असल में drop होती है जब इसका reference count zero तक पहुंचे।
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.