我正在阅读《铁 rust 》这本书来学习铁 rust ,目前正在学习所有权。它提到:
我们已经见过字符串常量,其中字符串值被硬编码到我们的程序中,字符串常量很方便,但它们并不适合我们可能想要使用文本的每一种情况,一个原因是它们是不可变的。
下面的代码运行起来没有任何问题。这里我改变了a
的值,如果不变的字符串可以被改变,那么这里说明的问题是什么?
fn main() {
let mut a = "Hello";
println!("{}", a);
a = " World";
println!("{}", a);
}
1条答案
按热度按时间bcs8qyzn1#
rust编译器生成的可执行二进制文件在只读数据段
rodata
中包含字符串常量"Hello"和"World"。因为这些文字被放置在一个不可变的节中,所以操作系统禁止修改它们。
x一个一个一个一个x一个一个二个x
但是,* 变量 *
a
的类型是&str
,所以是一个指向字符串切片的指针,它存在于堆栈中,因此,a
首先指向地址"Hello",然后指向地址"World"是完全有效的。unsafe
数据块的信息我们希望向
a
指向的地址写入一些内容,以表明它确实存储在只读段中。a
被声明为mut a: &str
,这意味着变量是可变的,但数据(字符串文字)是不可变的(与mut a: &mut str
相反),因此,编译器阻止我们使用a.as_mut_ptr()
来获取指向底层字节的可变(又称可写)指针。😉️). Thus, the compiler prevents us from usinga.as_mut_ptr()
to get a mutable (aka writable) pointer to the underlying bytes.相反,我们要做一个小把戏:使用
a.as_ptr()
并将返回的const *u8
强制转换为mut *u8
。最后,写入指针需要unsafe
块,因为您可能会违反Rust的内存安全,这可能会导致不好的事情发生,如上面所示的分段错误。