Open In App

Rust – Reference Counted Smart Pointer

Improve
Improve
Like Article
Like
Save
Share
Report

In Rust, there is a concept of a Smart pointer where we use multiple ownership explicitly using the Rc<T> type. This Rc <type> is referred to as Reference counting. This concept was introduced in Rust to handle scenarios where a single value of the variable has multiple owners. 

Rc<T> keeps how many references are made to a value and also checks whether it is still being referred. In case of no references i.e. Zero references to a value, the referenced value can be cleaned without any of the existing references being invalid.

 Rc <T> is particularly helpful in scenarios where data allocation is needed on the heap for some parts of our program and we are unable to track the last data in the heap.

Case 1: Sharing Data Using Rc <T>

Here, we are declaring GFG as a list. The Cons variants hold variable (_x) and that points to GFG. The number of references is made to Two once _y is created while cloning Rc<GFG> that _x is holding. We clone_x while creating _y so that the number of references is increased (3). Whenever Rc:: clone is called, the reference count to Rc<GFG> is increased and unless there are zero references, data is not cleaned.

Rust




// Rust program for Sharing data using Rc 
#![allow(dead_code)]
enum GFG {
    Cons(i32, Rc<GFG>),
    Nil,
}
  
use crate::GFG::{Cons, Nil};
use std::rc::Rc;
  
fn main() {
    let _x = Rc::new(Cons(10, Rc::new(Cons(10, Rc::new(Nil)))));
    let _y = Cons(20, Rc::clone(&_x));
    let _z = Cons(30, Rc::clone(&_x));
}


Output:

 

Case 2: Cloning the Rc<T> To Increase Reference Count

Here, we see that the variable _z goes out of scope when Rc<T> goes out of scope. Therefore, there is no need to call the function for decreasing the reference count (Rc::clone) for increasing the reference count.

Rust




// Rust program for Cloning the Rc<T> 
// to increase the Reference Count
enum GFG {
    Cons(i32, Rc<GFG>),
    Nil,
}
  
use crate::GFG::{Cons, Nil};
use std::rc::Rc;
  
fn main() {
    let _x = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
    println!("Value  creating _x = {}", Rc::strong_count(&_x));
    let _y = Cons(3, Rc::clone(&_x));
    println!("Value after creating _y = {}", Rc::strong_count(&_x));
    {
        let _z = Cons(4, Rc::clone(&_x));
        println!("Value after creating _z = {}", Rc::strong_count(&_x));
    }
    println!("Value _z goes out of scope = {}", Rc::strong_count(&_x));
}


Output:

 



Last Updated : 16 Sep, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads