rust

How can I get the heap address of an object?


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.


Solution

  • 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.)