Rust中的指针取消引用

d4so4syb  于 2022-11-12  发布在  其他
关注(0)|答案(2)|浏览(225)

我对下面的问题感到很困惑。如果我理解正确的话

let x = &42;

被内部膨胀到

let x_value = 42;
let x = &x;

我想我在《铁 rust 》一书中见过这一点,但我找不到它的参考文献。
我的问题与以下代码有关:

let x = 42;
let rx = &x;
let px = rx as *const i32 as *mut i32;
unsafe {
  *px = 0;
}
println!("{}", x);

正如预期的那样,这将打印0。但是,如果我写

let rx = &42;
let px = rx as *const i32 as *mut i32;
unsafe {
  println!("Deref");
  *px = 0;
}
println!("{}", x);

程序在打印出Deref后终止。很明显,当px被取消引用时出错了。我想我关于let x = &42在内部扩展的第一个评估是错误的。

2j4z5cfb

2j4z5cfb1#

您正在调用未定义的行为。来自Rust Reference:

12.3行为被视为未定义

以下是所有Rust代码中禁止的行为列表,包括不安全块和不安全函数。[...]

  • 改变不可变数据(即通过共享引用访问的数据或let绑定拥有的数据),除非该数据包含在UnsafeCell<U>中。

因为你正在改变不可变的数据,你正在调用未定义的行为。事实上,它在第一个版本中工作只是(坏)运气。

bkhjykvo

bkhjykvo2#

let x = 42;
let rx = &x;

这里你在stack上创建一个新的变量,并在那里写入来自程序代码的值42,所以当创建一个引用时,它引用的是stack上的这个值。您可以访问堆栈上的值并能够更改它。
在第二种情况下

let rx = &42;

你创建了一个直接指向存储代码(指令和其他数据)的内存部分中的值的引用。2而这部分内存是不可变的。

相关问题