rustlinked-listhashsetrefcell

Is RefCell::as_ptr guaranteed to stay the same for a given RefCell?


I am looking for a way to impl Hash for MyStruct where MyStruct contains `Rc<RefCell> (yes, it's a linked list of a sort).

This answer suggests std::ptr::hash(self.next.as_ref()), but I have doubts whether there are any guarantees reg the RefCell address.

In Ruby, I'd use object_id method inplace of as_ptr as a unique identifier to hash. If as_ptr may change during execution, is there any similar identifier for a given RefCell ?

I'm trying to solve https://leetcode.com/problems/copy-list-with-random-pointer/


Solution

  • No, RefCell::as_ptr is not guaranteed to be stable in the general case. An example:

    let a = RefCell::new(42);
    println!("address: {:?}", a.as_ptr());
    let b = Some(a);
    println!("address: {:?}", b.unwrap().as_ptr());
    

    Prints something like this:

    address: 0x7ffe3737d228
    address: 0x7ffe3737d300
    

    The reason is that the RefCell object was moved. See it in action on Playground.


    As for an actual solution: Rust doesn't make it easy, but there's a way. In your case, the object is an Rc<RefCell<_>>. The internal pointer of an immutable Rc cannot change since every Rc instance points to the same heap address. Thus, Rc::as_ref() is stable.

    I wrote some code that demonstrates using Rcs as HashMap keys by heap address, but it's not pretty: Playground.