[英]Is "String" always allocated on the heap?
In this Rust documentation , it is written that:在这份Rust 文档中,写道:
String is allocated on the heap.字符串分配在堆上。
However, when I look at the memory mapping, I see that it is allocated in the stack...但是,当我查看 memory 映射时,我发现它是在堆栈中分配的...
Let's consider the basic Rust source file below:让我们考虑下面的基本 Rust 源文件:
// rustc -o string_vs_str -C opt-level=0 -C debuginfo=2 main.rs
fn main() {
let my_string: String = String::from("abc");
let my_str: &str = "def";
println!("{}{}", my_string, my_str);
let my_string_str: &str = my_string.as_str();
println!("my_string_str: {}", my_string_str);
}
Let's executed RUST-GDB on the executable, upon the following commands:让我们根据以下命令在可执行文件上执行 RUST-GDB:
# rust-gdb --batch --command=test.gdb --args ./string_vs_str
set width 0
set height 0
set verbose off
### Set 2 breakpoints
b main.rs:6
b main.rs:8
### Start the process
r
### Display the memory mapping into the file "map.txt"
set logging redirect on
set logging file map.txt
set logging overwrite on
set logging enabled on
info proc map
set logging enabled off
### Get information about "my_string"
echo == my_string ==\n
print my_string
ptype my_string
print &my_string
print my_string.vec
c
### Get information about "my_str"
echo == my_str ==\n
print my_str
ptype my_str
print &my_str
print my_str.length
print my_str.data_ptr
The result is given below:结果如下:
Breakpoint 1, main::main () at main.rs:6
6 println!("{}{}", my_string, my_str);
== my_string ==
$1 = "abc"
type = struct alloc::string::String {
vec: alloc::vec::Vec<u8, alloc::alloc::Global>,
}
$2 = (*mut alloc::string::String) 0x7fffffffd960
$3 = Vec(size=3) = {97, 98, 99}
abcdef
Breakpoint 2, main::main () at main.rs:8
8 println!("my_string_str: {}", my_string_str);
== my_str ==
$4 = "def"
type = struct &str {
data_ptr: *mut u8,
length: usize,
}
$5 = (*mut &str) 0x7fffffffd978
$6 = 3
$7 = (*mut u8) 0x55555559304f
And the content of the (logged) file " map.txt
" is:而(记录的)文件“ map.txt
”的内容是:
process 11932
Mapped address spaces:
Start Addr End Addr Size Offset Perms objfile
...
0x5555555a5000 0x5555555c6000 0x21000 0x0 rw-p [heap]
0x7ffff7d5c000 0x7ffff7d5f000 0x3000 0x0 rw-p
...
0x7ffffffde000 0x7ffffffff000 0x21000 0x0 rw-p [stack]
0xffffffffff600000 0xffffffffff601000 0x1000 0x0 --xp [vsyscall]
Please note: I have removed some lines that I consider as not important.请注意:我删除了一些我认为不重要的行。
Unless I am mistaken:除非我记错了:
0x5555555a5000
and ends at 0x5555555c6000
.头部从0x5555555c6000
开始,到0x5555555a5000
结束。0x7ffffffde000
and ends at 0x7ffffffff000
.堆栈从0x7ffffffff000
开始,到0x7ffffffde000
结束。my_string
is allocated at 0x7fffffffd960
.变量my_string
分配在0x7fffffffd960
处。my_str
is allocated at 0x7fffffffd978
.变量my_str
分配在0x7fffffffd978
处。 OK.好的。 Thus, unless I am mistaken, both my_string
and my_str
are allocated in the stack:因此,除非我弄错了,否则my_string
和my_str
都分配在堆栈中:
VAR my_string VAR my_string
my_string
at 0x7fffffffd960
: my_string
位于0x7fffffffd960
处:
$ value="7fffffffd960" # address of my_string
$ start="7ffffffde000" # start of the stack
$ stop="7ffffffff000" # end of the stack
$ echo "obase=16;ibase=16;${value^^} > ${start^^}" | bc
1
$ echo "obase=16;ibase=16;${value^^} < ${stop^^}" | bc
1
Thus: 0x7ffffffde000 < &my_string < 0x7ffffffff000
=> my_string
is allocated in the stack.因此: 0x7ffffffde000 < &my_string < 0x7ffffffff000
=> my_string
在堆栈中分配。
VAR my_str VAR my_str
my_str.data_ptr
at 0x7fffffffd978
: 0x7fffffffd978
处的my_str.data_ptr
:
$ value="7fffffffd978" # address of my_str.data_ptr
$ start="7ffffffde000" # start of the stack
$ stop="7ffffffff000" # end of the stack
$ echo "obase=16;ibase=16;${value^^} > ${start^^}" | bc
1
$ echo "obase=16;ibase=16;${value^^} < ${stop^^}" | bc
1
Thus: 0x7ffffffde000 < &my_str.data_ptr < 0x7ffffffff000
=> my_str.data_ptr
is allocated in the stack.因此: 0x7ffffffde000 < &my_str.data_ptr < 0x7ffffffff000
=> my_str.data_ptr
被分配到栈中。
my_str.length
at 0x55555559304f
: my_str.length
在0x55555559304f
处:
$ value="55555559304f" # adress of my_str.length
$ start="5555555a5000" # start of the heap
$ stop="5555555c6000" # end of the heap
$ echo "obase=16;ibase=16;${value^^} > ${start^^}" | bc
0
$ echo "obase=16;ibase=16;${value^^} < ${stop^^}" | bc
1
Thus: &my_str.length
is not allocated in the stack nor it is in the heap.因此: &my_str.length
既不在栈中也不在堆中分配。
Conclusion:结论:
The structure that defines " str
" is allocated in the stack.定义“ str
”的结构分配在堆栈中。
The vector that defines the content of a "String" is also allocated in the stack.定义“字符串”内容的向量也在堆栈中分配。
What's wrong with this experiment?这个实验有什么问题?
The String
and &str
variables themselves are allocated on the stack (the length, data pointer and capacity for String
). String
和&str
变量本身在堆栈上分配( String
的长度、数据指针和容量)。 But the data they point at is allocated on the heap for String
, and at .rodata
for your &str
.但是它们指向的数据分配在String
的堆上,以及&str
的.rodata
上。
To see that, print my_string.vec.buf.ptr.pointer.pointer
(yep, that's long) and my_str.data_ptr
.要看到这一点,请打印my_string.vec.buf.ptr.pointer.pointer
(是的,那很长)和my_str.data_ptr
。 You will see that the first points at the heap and the second is mapped to the executable.您将看到第一个指向堆,第二个指向可执行文件。 These are the data pointers.这些是数据指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.