取消引用指向已删除值的指针,内存仍然存在

问题描述 投票:0回答:2

我正在玩不安全的 Rust 并尝试实现,但我发现了一些我不明白的东西。我确信我会有一个悬空指针,并且在尝试运行它时会遇到某种运行时错误,但我没有。

fn main() {
    let s1 = String::from("s1");
    let s1_raw_ptr: *const String = &s1;
    drop(s1);
    
    unsafe {
        let s = &*s1_raw_ptr;
        println!("s recovered from raw pointer: {:?}", s);
    }
}

输出:

s recovered from raw pointer: "s1"

我认为当一个值超出 Rust 的范围时,它会立即被清理。取消引用原始指针到现已删除的值是如何工作的?

rust unsafe
2个回答
2
投票

当在 Rust 中删除一个字符串时,最终被调用的是系统分配器上的

Allocator::deallocate
。此后,使用数据是未定义的行为,所以任何事情都可能发生!但在实践中,如果没有任何时髦的编译器优化,往往会发生的情况是,您只是获得内存中存储的任何数据。如果该位置没有任何新的分配,那么您只需获取之前的任何数据即可。

释放内存分配时,该分配不会发生任何变化。通过将数据设置为全零(或其他值)来清除数据是没有意义的,因为任何新分配的内存始终需要由该内存的用户初始化。


0
投票

它是一个悬空指针,旧数据恰好还在那里。不存在运行时错误,因为没有原因,它只是未定义的行为。您将一个字符串写入内存,然后将其删除,然后再次从同一内存中读取。但删除它并不会覆盖该内存,即使覆盖了,也不会导致错误。您认为会出现错误的原因是悬空指针通常不会指向同一事物,并且尝试对该数据执行某些操作会导致错误。悬空指针本身不会导致任何错误。

总而言之,它被“清理”了,但实际上没有内存被覆盖。

© www.soinside.com 2019 - 2024. All rights reserved.