如果指针的地址是64位,为什么它在打印时显示为6个字节?

mko*_*mko 10 c pointers

#include <stdio.h>
int main(void){
  int *ptr;
  printf("the value of ptr is %p",ptr);
}
Run Code Online (Sandbox Code Playgroud)

这给了我0x7fffbd8ce900,这只有6个字节.应该是8字节(64位)?

Wyz*_*a-- 14

虽然指针是64位,但是当前处理器实际上只支持48位,因此地址的高两个字节总是0000或(由于符号扩展)FFFF.

将来,如果48位不再足够,新处理器可以添加对56位或64位虚拟地址的支持,并且现有程序将能够利用额外空间,因为它们已经在使用64位指针.


Joh*_*eek 6

这只意味着前两个字节为零(顺便提一下,目前保证x86-64芯片 - 但在这种情况下,这并不意味着什么,因为你的指针没有被初始化).%p允许截断前导零,就像任何其他数字类型一样.%016p然而,事实并非如此.这应该工作正常:

printf("the value of ptr is %016p", ptr);
Run Code Online (Sandbox Code Playgroud)


Hou*_*Lee -6

因为6字节地址只是虚拟地址(实际物理地址的偏移量)。在物理架构中(例如 X86),内存被划分为多个部分,这些部分可以通过单个索引寄存器进行寻址,而无需更改 16 位段选择器。在X86-CPU的实模式下,一个段总是使用16位(2字节)段选择器,它会在程序开始运行时(即创建实际运行的进程)由操作系统动态决定)。

因此,如果您的变量具有 48 位地址 0x7fffbd8ce900,并且您的程序具有段选择器偏移量 08af,并且变量的实际地址为 (0x08af<<48)+0x7fffbd8ce900 = 0x08af7fffbd8ce900,即 64 位。

进一步阅读请转到: x86 内存分段

  • 在仔细检查了32位和64位架构之间的差异后,我发现在64位架构中,不再有用于寻址的段选择器结构,所以,非常抱歉给出了错误的答案。此外,非常感谢 Wyzard 和 BoPersson 指出我的错误并更新我的知识 (6认同)
  • 这个答案是不正确的。现代操作系统使用没有分段的平面虚拟地址空间,并且 64 位模式(“长模式”)甚至不支持分段。所讨论的 16 位“不是”段选择器的位置。 (3认同)