Memory 为什么打印的内存地址是40位和48位地址的混合体?
我试图理解Rust处理内存的方式,我有一个小程序,可以打印一些内存地址:Memory 为什么打印的内存地址是40位和48位地址的混合体?,memory,rust,Memory,Rust,我试图理解Rust处理内存的方式,我有一个小程序,可以打印一些内存地址: fn main() { let a = &&&5; let x = 1; println!(" {:p}", &x); println!(" {:p} \n {:p} \n {:p} \n {:p}", &&&a, &&a, &a, a); } 这将打印以下内容(不同的运行会有所不同): 0x235d0ff61
fn main() {
let a = &&&5;
let x = 1;
println!(" {:p}", &x);
println!(" {:p} \n {:p} \n {:p} \n {:p}", &&&a, &&a, &a, a);
}
这将打印以下内容(不同的运行会有所不同):
0x235d0ff61c
0x235d0ff710
0x235d0ff728
0x235d0ff610
0x7ff793f4c310
这实际上是40位和48位地址的混合。为什么是这种混合?另外,有人能告诉我为什么地址(2、3、4)不在8字节分隔的位置(因为
std::mem::size\u of val(&a)
给出了8)?我在AMD x-64处理器(Phenom | | X4)上运行Windows 10,内存为24GB。所有地址的大小都相同,Rust只是不打印尾随的0位数字
实际内存布局是操作系统的一个实现细节,但是a
在不同于所有其他变量的内存区域中打印位置的原因是a
实际上存在于加载的二进制文件中,因为它是一个编译器已经可以计算的值。所有其他变量都是在运行时计算的,并在堆栈上运行
请参见以下内容的汇编结果:
.L_uunnamed_4
包含值5.L_uunnamed_5
、.L_uunnamed_6
和.L_uunnamed_1
是&5
和&5
因此,.L_uunnamed_1
是您系统上位于0x7ff793f4c310
的位置。当0x235d0ff???
在堆栈上并在代码的红色和蓝色区域中计算时
这实际上是40位和48位地址的混合。为什么是这种混合
这不是一个真正的混合,Rust只是不显示前导零。它实际上是关于操作系统在地址空间中映射程序的各个组件(数据、bss、堆和堆栈)的位置
另外,有人能告诉我为什么地址(2、3、4)不在以8字节分隔的位置(因为std::mem::size_of_val(&a)给出了8)
因为println
是一个宏,它在stackframe中扩展为一组内容,因此在frame final code()中,您的值不会彼此相邻地定义。尽管即使是这样,也不能保证编译器不会重用现在的死内存来节省帧大小