Rust 字符串文字值是否存储在堆上?

问题描述 投票:0回答:2

考虑这个简单的代码

fn main () {
    let mut s: &str = "hello";
    s = "hey";
    println! ("{}", s);
}

我了解到字符串文字本质上是不可变的。我同意这一点,因为这里的变量“s”指的是值“hello”的第一个字符的地址。所以基本上它是一个指针。现在,如果我将 s 的值更改为“hey”,这并不是在内存中的某个位置“就地”替换值“hello”,但它本质上是创建一个新的地址位置,将值“hey”存储在它并获取该地址并将其绑定到 s。这个很好理解。

但是我感到困惑的是,由于必须在编译时知道变量的大小才能将它们放置在堆栈上,那么字符串文字也存储在堆栈上还是堆上?它们可能存储在堆栈上作为硬编码值。但如果是这样只能在运行时确定的东西呢?

fn main () {
 
    let mut user_input = String::new();
    let stdin = io::stdin(); // We get user input whose size we can't predict 
    stdin.read_line(&mut user_input);
    
    let ab = user_input.as_str(); // taking the value on heap and turning it to string literal and creating a new reference pointer 'ab' on the stack 

    println!("input {}, {} ", user_input, ab);

}

上面的字符串文字值“ab”存储在哪里?堆栈还是堆?

rust stack heap-memory
2个回答
1
投票

那么字符串文字也存储在堆栈中还是堆中?

都不是。字符串文字通常存储在生成的可执行文件的“rodata”(只读数据)段中。

但是如果是这样只能在运行时确定的东西怎么办?

根据定义,字符串文字不是在运行时确定的。

上面的字符串文字值“ab”存储在哪里?堆栈还是堆?

字符串slice

&str
)不是字符串文字,它是指向非拥有字符串的指针。当您写入
user_input.as_str()
时,您只会获得第二个指向存储在
user_input
中的字符串的指针。

参见 https://doc.rust-lang.org/book/ch04-03-slices.html


1
投票

字符串文字的类型为

&'static str
。注意
'static
部分。它们被放置在二进制文件的只读存储器中。它不是堆栈也不是堆。您的操作系统在启动进程时分配此内存。这与您编写的内容相同:

static FOO: usize = 42;

Rust 会将其放置在二进制文件的只读部分中。并且您可以获得对它的

'static
引用,因为只要您的进程存在,该内存就始终有效。

至于字符串文字的大小,编译器显然知道它的大小,因此它知道为它们保留多少内存。

&str
实际上被称为宽指针或胖指针,因为它有两个字(指针)的大小。它保存一个指向内存的指针,其中字符串文字(或任何其他字符串切片)开始及其长度。您可以将其视为
(*const u8, usize)
。因此字符串切片可以指向包含字符串的any内存。它是堆栈、堆还是二进制文件中的其他数据段并不重要。

您可以阅读 The Rust Book 中的关于切片的章节,以更好地理解这个概念。

© www.soinside.com 2019 - 2024. All rights reserved.