Den*_*ive 4 string heap-memory stack-memory rust
在这个Rust 文档中,写道:
字符串是在堆上分配的。
但是,当我查看内存映射时,我发现它是在堆栈中分配的......
让我们考虑下面的基本 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);
}
Run Code Online (Sandbox Code Playgroud)
让我们根据以下命令在可执行文件上执行 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
Run Code Online (Sandbox Code Playgroud)
结果如下:
# 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
Run Code Online (Sandbox Code Playgroud)
(记录的)文件“ ”的内容map.txt是:
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
Run Code Online (Sandbox Code Playgroud)
请注意:我删除了一些我认为不重要的行。
除非我记错了:
0x5555555a5000并结束于0x5555555c6000。0x7ffffffde000并结束于0x7ffffffff000。my_string分配在0x7fffffffd960。my_str分配在0x7fffffffd978。好的。因此,除非我弄错了,否则my_string和 都my_str在堆栈中分配:
VAR my_string
my_string在0x7fffffffd960:
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]
Run Code Online (Sandbox Code Playgroud)
因此:0x7ffffffde000 < &my_string < 0x7ffffffff000=>my_string在堆栈中分配。
VAR my_str
my_str.data_ptr在0x7fffffffd978:
$ 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
Run Code Online (Sandbox Code Playgroud)
因此:0x7ffffffde000 < &my_str.data_ptr < 0x7ffffffff000=>my_str.data_ptr在堆栈中分配。
my_str.length在0x55555559304f:
$ 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
Run Code Online (Sandbox Code Playgroud)
因此:&my_str.length不在堆栈中分配,也不在堆中分配。
结论:
定义“ ”的结构体str在栈中分配。
定义“字符串”内容的向量也在堆栈中分配。
这个实验有什么问题吗?
和变量本身在堆栈上分配(长度String、&str数据指针和容量String)。但它们指向的数据分配在 的堆上String,并分配.rodata给您的&str。
要查看这一点,请打印my_string.vec.buf.ptr.pointer.pointer(是的,很长)和my_str.data_ptr. 您将看到第一个指向堆,第二个指向可执行文件。这些是数据指针。
| 归档时间: |
|
| 查看次数: |
706 次 |
| 最近记录: |