为什么第二个变量的地址不在第一个变量之后?
Why is the address of a second variable not right after the first variable?
我知道在 64 位系统上,Vec
将存储一个指向堆的 8 字节指针,8 字节用于容量,8 字节用于长度。
我假设a
的地址紧跟在v
的地址之后,但是当我检查堆栈上向量分配的边界时,我发现它总是占用31个字节堆栈内存,比应有的多 7 个字节。字符串也是如此。
pub fn main() {
let v = vec![1_u8];
let a = 1_u8;
let v_raw = &v as *const _;
let a_raw = &a as *const _;
println!("v addr = {:p}, dec = {}", v_raw, v_raw as usize);
println!("a addr = {:p}, dec = {}", a_raw, a_raw as usize);
println!("offset = {} bytes", a_raw as usize - v_raw as usize);
// changing below 3 print will affect the mysterious 7 bytes
// println!("v_raw addr = {:p}", &v_raw); // (1)
// println!("a_raw addr = {:p}", &a_raw); // (2)
println!("v as_ptr = {:p}", v.as_ptr()); // (3)
// dereference through offset 24 to 30 -> 7 bytes
let mut offset = 24_usize;
loop {
if offset == 31 {
break;
}
// usize to *const usize(raw pointer)
let mut addr = (v_raw as usize + offset) as *const usize;
let deref_value = unsafe { *addr as u8 };
println!(
"offset = {}, addr = {:p}, value hex = {:x}, value = {}",
offset, addr, deref_value, deref_value
);
offset += 1;
}
}
v addr = 0x7fffbcf48b70, dec = 140736363531120
a addr = 0x7fffbcf48b8f, dec = 140736363531151
offset = 31 bytes
v as_ptr = 0x55d9c823ea40
offset = 24, addr = 0x7fffbcf48b88, value hex = 0, value = 0
offset = 25, addr = 0x7fffbcf48b89, value hex = 0, value = 0
offset = 26, addr = 0x7fffbcf48b8a, value hex = 0, value = 0
offset = 27, addr = 0x7fffbcf48b8b, value hex = 0, value = 0
offset = 28, addr = 0x7fffbcf48b8c, value hex = 0, value = 0
offset = 29, addr = 0x7fffbcf48b8d, value hex = 0, value = 0
offset = 30, addr = 0x7fffbcf48b8e, value hex = 0, value = 0
有时这 7 个额外地址包含所有 0 值,有时如果我取消注释所有标记为 (1)(2)(3)
的 println!
宏则不会
当我依次声明 v
和 a
时,我期望 a
在堆栈上紧挨着 v
,所以为什么我得到这 7字节额外?这个额外的内存是为一些特殊的东西设计的吗?
I assume that the address of a
is right after the address of v
.
仅仅因为你按这个顺序写了这些变量并不意味着 Rust 会把它们连续存储在堆栈上。 Rust 编译器可以自由地将东西放在内存中它认为合适的地方,你绝对不能依赖顺序。最终顺序可能会有所不同,具体取决于:
- Rust 编译器的版本
- 如果您正在编译调试或发布
- 目标操作系统
- 目标CPU架构
- 您的应用程序附近的其他代码
Vec
的实际大小可以显示为24:
let v = vec![1_u8];
println!("size = {}", std::mem::size_of_val(&v)); // size = 24
另请参阅:
- Why do subsequent Rust variables increment the stack pointer instead of decrementing it?
我知道在 64 位系统上,Vec
将存储一个指向堆的 8 字节指针,8 字节用于容量,8 字节用于长度。
我假设a
的地址紧跟在v
的地址之后,但是当我检查堆栈上向量分配的边界时,我发现它总是占用31个字节堆栈内存,比应有的多 7 个字节。字符串也是如此。
pub fn main() {
let v = vec![1_u8];
let a = 1_u8;
let v_raw = &v as *const _;
let a_raw = &a as *const _;
println!("v addr = {:p}, dec = {}", v_raw, v_raw as usize);
println!("a addr = {:p}, dec = {}", a_raw, a_raw as usize);
println!("offset = {} bytes", a_raw as usize - v_raw as usize);
// changing below 3 print will affect the mysterious 7 bytes
// println!("v_raw addr = {:p}", &v_raw); // (1)
// println!("a_raw addr = {:p}", &a_raw); // (2)
println!("v as_ptr = {:p}", v.as_ptr()); // (3)
// dereference through offset 24 to 30 -> 7 bytes
let mut offset = 24_usize;
loop {
if offset == 31 {
break;
}
// usize to *const usize(raw pointer)
let mut addr = (v_raw as usize + offset) as *const usize;
let deref_value = unsafe { *addr as u8 };
println!(
"offset = {}, addr = {:p}, value hex = {:x}, value = {}",
offset, addr, deref_value, deref_value
);
offset += 1;
}
}
v addr = 0x7fffbcf48b70, dec = 140736363531120
a addr = 0x7fffbcf48b8f, dec = 140736363531151
offset = 31 bytes
v as_ptr = 0x55d9c823ea40
offset = 24, addr = 0x7fffbcf48b88, value hex = 0, value = 0
offset = 25, addr = 0x7fffbcf48b89, value hex = 0, value = 0
offset = 26, addr = 0x7fffbcf48b8a, value hex = 0, value = 0
offset = 27, addr = 0x7fffbcf48b8b, value hex = 0, value = 0
offset = 28, addr = 0x7fffbcf48b8c, value hex = 0, value = 0
offset = 29, addr = 0x7fffbcf48b8d, value hex = 0, value = 0
offset = 30, addr = 0x7fffbcf48b8e, value hex = 0, value = 0
有时这 7 个额外地址包含所有 0 值,有时如果我取消注释所有标记为 (1)(2)(3)
的println!
宏则不会
当我依次声明 v
和 a
时,我期望 a
在堆栈上紧挨着 v
,所以为什么我得到这 7字节额外?这个额外的内存是为一些特殊的东西设计的吗?
I assume that the address of
a
is right after the address ofv
.
仅仅因为你按这个顺序写了这些变量并不意味着 Rust 会把它们连续存储在堆栈上。 Rust 编译器可以自由地将东西放在内存中它认为合适的地方,你绝对不能依赖顺序。最终顺序可能会有所不同,具体取决于:
- Rust 编译器的版本
- 如果您正在编译调试或发布
- 目标操作系统
- 目标CPU架构
- 您的应用程序附近的其他代码
Vec
的实际大小可以显示为24:
let v = vec![1_u8];
println!("size = {}", std::mem::size_of_val(&v)); // size = 24
另请参阅:
- Why do subsequent Rust variables increment the stack pointer instead of decrementing it?