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
}
I created
p1pointer. Print its strong count as 1then 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?
That's the whole point of
Rc-Rcis 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 theRcor the inner object.In your case,
p1.clone()is equivalent toRc::clone(&p1).If you want to clone the inner
String, you need to doString::clone(&p1), or(*p1).clone().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, useBoxinstead ofRc. The two are very similar apart of the fact thatRcis for shared ownership.