【问题标题】:Why isn't it undefined behavior to use ptr::read() on a dropped Box?为什么在丢弃的盒子上使用 ptr::read() 不是未定义的行为?
【发布时间】: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。未定义的行为结论增加了更多权重:)

标签: rust undefined-behavior


【解决方案1】:

“未定义行为”包括“它似乎工作正常”。当涉及到未定义行为时,您可能犯的最严重错误是将正确结果解释为不存在未定义行为。

顺便说一句,它对我不起作用(每次运行时值都会改变)。

$ cargo run
     Running `target/debug/so-ub`
The value of y is -500126584

【讨论】:

  • 非常感谢弗朗西斯!我很确定这是未定义的行为(肯定会在 C 中),但考虑到我对 Rust 的缺乏经验,我只想仔细检查一下。
猜你喜欢
  • 1970-01-01
  • 2021-12-28
  • 2010-12-22
  • 2019-05-21
  • 2011-05-05
  • 1970-01-01
  • 2015-05-22
  • 2013-11-01
相关资源
最近更新 更多