Why does cloning an Rc pointer in Rust increase its strong_count?

304 Views Asked by At

I have this function:

use std::rc::Rc;

fn rc_counter() -> Rc<String> {
    let p1 = Rc::new(String::from("Hello"));
    println!("count {}", Rc::strong_count(&p1)); // 1
                                                 // this is an owned type not a reference
    let p2 = p1.clone();
    println!(
        "Count after the clone is created for the pointer {}",
        Rc::strong_count(&p1)
    ); // 2
    p2
}
  1. I created p1 pointer. Print its strong count as 1

  2. then I cloned it and checked the strong count of "p1" and it prints out 2.

As far as I know, cloning means, replicating the pointer in stack and replicating the data in the heap. But looks like cloned p2 is still related to the p1. How is this possible?

1

There are 1 best solutions below

4
Finomnis On

That's the whole point of Rc - Rc is a reference counting smart pointer for shared ownership. It makes it possible that multiple owners own it simultaneously.

To not break Rust's ownership rules, all of the owners can only access it immutably, though.

For that reason, .clone() is kind of discouraged, because it doesn't make it clearly readable whether it clones the Rc or the inner object.

In your case, p1.clone() is equivalent to Rc::clone(&p1).

If you want to clone the inner String, you need to do String::clone(&p1), or (*p1).clone().


As far as I know, cloning means, replicating the pointer in stack and replicating the data in the heap. But looks like cloned p2 is still related to the p1.

You are describing the behavior of Box. If you want non-shared ownership of an object on the heap, and if you clone it it also clones the object on the heap, use Box instead of Rc. The two are very similar apart of the fact that Rc is for shared ownership.