Rust 编译器通过禁止赋值给借来的值来防止什么灾难?
例如: 编译器不允许这样做: 错误[E0506]:无法分配给's',因为它是借用的 ->src/main.rs:13:17 | 12 | IntOrString::Sref p=>{ |---s的借词出现在这里 13 | s=IntOrString::I0xdeadbeef; |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^此处发生借来的's'的赋值 但是,假设是这样,那是怎么回事 现在p是一个&字符串,指向内存,这是我们选择的intRust 编译器通过禁止赋值给借来的值来防止什么灾难?,rust,borrowing,Rust,Borrowing,例如: 编译器不允许这样做: 错误[E0506]:无法分配给's',因为它是借用的 ->src/main.rs:13:17 | 12 | IntOrString::Sref p=>{ |---s的借词出现在这里 13 | s=IntOrString::I0xdeadbeef; |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^此处发生借来的's'的赋值 但是,假设是这样,那是怎么回事 现在p是一个&字符串,指向内存,这是我们选择的int 是一件坏事吗?让我们为所涉及
是一件坏事吗?让我们为所涉及的类型建立一个内存布局。IntOrString将有一个字节来确定它是0=数字、1=字符串的变量,然后是4个字节,这些字节将是一个数字或一组UTF-8字符开头的地址 让我们在内存中的0x100处分配s。变量在0x100处,值在0x101、0x102、0x103、0x104处。此外,假设值的内容是指针0xABCD;这是字符串的字节所在位置 当使用match arm IntOrString::Sref p时,p将被设置为值0x101-它是对该值的引用,该值从0x101开始。当您尝试使用p时,处理器将转到地址0x101,从地址读取该值,然后从该地址读取数据 如果编译器允许您在此时更改,则新数据的新字节将替换存储在0x101处的值。在本例中,存储在该值处的地址现在将指向任意的0xDEADBEEF。如果我们尝试使用字符串,我们将开始读取极不可能与UTF-8 da对应的内存字节助教 所有这些都不是学术性的,这种问题可能发生在格式良好的C程序中。在好的情况下,程序会崩溃。在坏的情况下,有可能读取程序中不应该读取的数据。甚至有可能注入外壳代码,使攻击者能够运行他们在程序中编写的代码
请注意,上面的内存布局非常简单,实际字符串更大、更复杂。让我们为所涉及的类型组成一个内存布局。IntOrString将有一个字节来确定哪个变量是0=number,1=String,然后是4个字节,它们将是一个数字或一组o开头的地址f UTF-8个字符 让我们在内存中的0x100处分配s。变量在0x100处,值在0x101、0x102、0x103、0x104处。此外,假设值的内容是指针0xABCD;这是字符串的字节所在位置 当使用match arm IntOrString::Sref p时,p将被设置为值0x101-它是对该值的引用,该值从0x101开始。当您尝试使用p时,处理器将转到地址0x101,从地址读取该值,然后从该地址读取数据 如果编译器允许您在此时更改,则新数据的新字节将替换存储在0x101处的值。在本例中,存储在该值处的地址现在将指向任意的0xDEADBEEF。如果我们尝试使用字符串,我们将开始读取极不可能与UTF-8 da对应的内存字节助教 所有这些都不是学术性的,这种问题可能发生在格式良好的C程序中。在好的情况下,程序会崩溃。在坏的情况下,有可能读取程序中不应该读取的数据。甚至有可能注入外壳代码,使攻击者能够运行他们在程序中编写的代码
请注意,上面的内存布局非常简化,而实际字符串更大、更复杂。我对您的要求感到非常困惑。正如您所注意的,编译器阻止编译此代码。注释指的是如果编译器允许,可能会发生的情况,但由于编译器不允许,因此无所谓uld说现在p包含我的电话号码和中奖彩票号码,并且同样有效。我只是想了解编译器阻止了什么灾难的发生。是的,实际上这并不重要,但洞察力仍然很有价值。我对你的问题感到非常困惑。正如你所注意到的,编译器阻止了这段代码的编译。不是吗他的评论是指如果编译器允许的话可能会发生什么,但既然编译器不允许,那就没关系了。评论可以说现在p包含了我的电话号码和中奖彩票号码,并且同样有效。我只想了解编译器阻止了什么灾难的发生。是的,实际上没关系,但是e洞察仍然很有价值。
#[derive(Debug)]
enum IntOrString {
I(isize),
S(String),
}
fn corrupt_enum() {
let mut s = IntOrString::S(String::new());
match s {
IntOrString::I(_) => (),
IntOrString::S(ref p) => {
s = IntOrString::I(0xdeadbeef);
// Now p is a &String, pointing at memory
// that is an int of our choosing!
}
}
}
corrupt_enum();