为什么在放置的 Box 上使用 ptr::read() 不是未定义的行为?
Why isn't it undefined behavior to use ptr::read() on a dropped Box?
我正在测试 Rust 的一些不安全功能,主要是 std::ptr
函数,以查看我可能导致未定义行为的方式(出于好奇)。在下面的示例中,我使用 std::ptr::read()
将存储在 x
中的地址移动到 y
而不取消初始化 x
.
读取后我认为我有两个指向堆上相同位置的指针。我的印象是,当我离开定义 x
的块时,x
的析构函数将是 运行,导致 y
指向释放的内存。但是,当我去打印 *y
的值时,它仍然打印出正确的值 10。我阅读了文档,但似乎无法弄清楚为什么这不是 UB。如果有人能为我澄清这一点,我将不胜感激。
PS。我来自 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);
}
"Undefined Behavior" 包括 "it appears to work correctly"。当涉及未定义行为时,您可能犯的最严重错误是将正确结果解释为不存在未定义行为。
它不 对我有用,顺便说一句(并且每个 运行 的值都会改变)。
$ cargo run
Running `target/debug/so-ub`
The value of y is -500126584
我正在测试 Rust 的一些不安全功能,主要是 std::ptr
函数,以查看我可能导致未定义行为的方式(出于好奇)。在下面的示例中,我使用 std::ptr::read()
将存储在 x
中的地址移动到 y
而不取消初始化 x
.
读取后我认为我有两个指向堆上相同位置的指针。我的印象是,当我离开定义 x
的块时,x
的析构函数将是 运行,导致 y
指向释放的内存。但是,当我去打印 *y
的值时,它仍然打印出正确的值 10。我阅读了文档,但似乎无法弄清楚为什么这不是 UB。如果有人能为我澄清这一点,我将不胜感激。
PS。我来自 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);
}
"Undefined Behavior" 包括 "it appears to work correctly"。当涉及未定义行为时,您可能犯的最严重错误是将正确结果解释为不存在未定义行为。
它不 对我有用,顺便说一句(并且每个 运行 的值都会改变)。
$ cargo run
Running `target/debug/so-ub`
The value of y is -500126584