Can you cast a memory address as a usize into a reference with a lifetime?
Asked Answered
M

1

8

I know we can cast from reference -> raw pointer -> address (usize), but can we do it backwards especially with lifetime annotations? For example, I have following code:

struct Name<'a> {
    name: &'a str,
}

impl<'a> Name<'a> {
    fn to_addr<'b>(&'b self) -> usize { /* ... */ }
    fn from_addr<'b>(address: usize) -> &'b Name<'a> {
        // assuming the address is valid,
        // is this even possible to return an reference with both lifetimes?
    }
}
Melissa answered 14/3, 2021 at 5:24 Comment(0)
F
17

It's unsafe, but yes:

fn from_addr<'b>(address: usize) -> &'b Name<'a> {
    unsafe { &*(address as *const Self) }
}

You have to ensure Rust's memory safety requirements yourself: the pointer must be non-null, non-dangling, aligned, not mutably aliased, etc. on top of ensuring the lifetimes are correct.

I'd actually mark this whole function as unsafe since the lifetime 'b (and depending on usage 'a) is determined at the call-site. The caller should know that there are guarantees it needs to ensure in order to use it safely.

unsafe fn from_addr<'b>(address: usize) -> &'b Name<'a> {
    &*(address as *const Self)
}
Forras answered 14/3, 2021 at 6:0 Comment(1)
The as_ref method on the pointers is also an option.Aldred

© 2022 - 2024 — McMap. All rights reserved.