【发布时间】:2023-03-15 15:13:01
【问题描述】:
我正在测试 Rust 的一些不安全功能,主要是 std::ptr 函数,以了解我可能导致未定义行为的方式(只是出于好奇)。在下面的示例中,我使用std::ptr::read() 将存储在x 中的地址移动到y,而不取消初始化x。
读取后,我认为我有两个指向堆上相同位置的指针。我的印象是,当我离开定义x 的块时,x 的析构函数将运行,导致y 指向释放的内存。但是,当我打印*y 的值时,它仍然打印出正确的值 10。我阅读了文档,但似乎无法弄清楚为什么这不是 UB。如果有人能为我澄清这一点,我将不胜感激。
附言。我来自 C 背景,所以对 C 的解释可能会让你更容易理解实际发生的事情。
fn main() {
let mut y: Box<i32>;
{
let x: Box<i32> = Box::new(10 as i32);
unsafe {
y = ptr::read(&x);
}
}
// I thought the destructor (free) would be called here on x
// making y point to invalid memory
// However, the following call to println! still works
println!("The value of y is {}", *y);
}
【问题讨论】:
-
我会说这是未定义的行为.. 因为,it doesn't work on the playground。此外,在 Debug 和 Release 之间进行更改也会更改 Playground 上的输出。更有趣的是,printing it within the unsafe block makes it work on the playground consistently。
-
这不是很奇怪吗?昨晚我在使用操场,它不会崩溃,但现在它会崩溃。感谢西蒙的评论。
-
出于好奇,您在 Playground 上使用什么浏览器?我觉得我在使用 Firefox 时出现了奇怪的行为。
-
我用的是 Chrome。未定义的行为结论增加了更多权重:)