-1

fn test() -> *const Vec<u8> {
    let b = vec![9_u8];
    let ret: *const Vec<u8> = &b;
    println!("ret ptr={:#p} inside {:#p}", ret, b.as_ptr());
    std::mem::forget(b);
    ret
}

fn main() {
    let a = test();
    let v = unsafe {
        &*a
    };
    println!("ret ptr={:#p} inside {:#p} value={}", v, v.as_ptr(), v[0]);
    println!("ret ptr={:#p} inside {:#p} value={}", v, v.as_ptr(), v[0]);
}

im my machine this gives:

ret ptr=0x00007fffc5d85690 inside 0x00005650a61cfaa0
ret ptr=0x00007fffc5d85690 inside 0x00005650a61cfaa0 value=9
ret ptr=0x00007fffc5d85690 inside 0x00005650a572a348 value=76

the problem in the last line where the value changes suddenly, is this some kind of bug ?

  • If you run the program through `cargo miri` (e.g. on the playground), miri will immediately point out hat `&*a` is dereferencing a freed pointer, so its undefined behavior, so the program has to sensible output at all. – user2722968 Aug 11 '23 at 22:58

1 Answers1

8

By using std::mem::forget, you've avoided dropping the Vec such that the 9_u8 will persist. However, your reference is is pointing to b which is a local variable and thus its memory will still be reclaimed for other function calls (as evidenced by the println!s). So the value you get from v[0] afterwards is nonsense.

By the way, the safe way to do what you've essentially done is to use Vec::leak.

kmdreko
  • 42,554
  • 6
  • 57
  • 106