为什么这个指针在 Rust 中释放之前会被垃圾收集

Nou*_*leb -1 garbage-collection pointers memory-management unsafe rust


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]);
}

Run Code Online (Sandbox Code Playgroud)

我的机器给出了:

ret ptr=0x00007fffc5d85690 inside 0x00005650a61cfaa0
ret ptr=0x00007fffc5d85690 inside 0x00005650a61cfaa0 value=9
ret ptr=0x00007fffc5d85690 inside 0x00005650a572a348 value=76
Run Code Online (Sandbox Code Playgroud)

最后一行的问题是值突然改变,这是某种错误吗?

kmd*_*eko 8

通过使用std::mem::forget,您可以避免删除Vec将持续存在的9_u8。但是,您的引用指向的是b局部变量,因此它的内存仍将被回收以供其他函数调用(如 s 所示println!)。所以你之后得到的值v[0]就是废话。

顺便说一句,完成您本质上所做的事情的安全方法是使用Vec::leak.