Is there anyway I can find the address on the heap that a struct points to? I think I can get heap address from an Rc, but I also want to see the address of the original object. I'm new to rust and am trying to understand how smart pointers work.
use std::rc::Rc;
struct Node {
value: i32,
right: Option<Rc<Node>>
}
fn main() {
let n = Node {value: 10, right: None};
println!("{:p}", &n);
println!("{:p}", &n as *const _);
let rc_new = Rc::new(n);
let rc_clone = Rc::clone(&rc_new);
let as_ptr = Rc::as_ptr(&rc_new);
println!("new {:p} {:p}", &rc_new, rc_new);
println!("clone {:p} {:p}", &rc_new, rc_new);
println!("as_ptr {:p} {:p}", &as_ptr, as_ptr);
}
Output
0x16aeba9d8
0x16aeba9d8
new 0x16aebaaa8 0x600003099230
clone 0x16aebaaa8 0x600003099230
as_ptr 0x16aebaab8 0x600003099230
I also tried println!("{:p}", n.as_bytes() as *const _)
with a String, but seems like Rc::new() on a string is creating a new copy of the data on the heap.
Just to be clear, the original struct n
was not on the heap. n
was on the stack. The address you're finding is the address of the copy of n
moved to the heap by Rc::new()
.
And you are finding it: it's the 0x600003099230
value that you see printed when you print as_ptr
. Note that it's the same value when you print the Rc
objects(*). That's why it's consistent. One way to prove to yourself that that's the address of the copy of n
inside rc_new
is by using the raw pointer:
unsafe {
// get the raw pointers and see if they're the same
println!("new and clone equal? {}", Rc::as_ptr(&rc_new) == Rc::as_ptr(&rc_clone));
// dereference as a Node and get its contents
println!("as_ptr value {}", (*as_ptr).value);
}
new and clone equal? true as_ptr value 10
(* Note you had a typo when printing rc_clone
, but if you fix that you'll also see the same value as for rc_new
.)