C++的一个指针占内存几个字节?

C++的一个指针占内存几个字节?

结论: 取决于是64位编译模式还是32位编译模式(注意,和机器位数没有直接关系)

  • 在64位编译模式下,指针的占用内存大小是8字节
  • 在32位编译模式下,指针占用内存大小是4字节

实验:(实验环境 vs2019)

  • 64位编译模式下
    C++的一个指针占内存几个字节?

    64位编译模式下,sizeof返回的是unsigned long long类型,占8字节

  • 32位编译模式下
    C++的一个指针占内存几个字节?

    32位编译模式下,sizeof返回的是unsgined int类型,占4字节

分析:
细心的同学可能会发现,为何 int* 和 stu* 类型的指针的大小一样呢?

  • 因为指针的本身的值就是内存地址,它的占用字节数也就是该程序能够访问内存地址的空间大小,比如32位编译模式下,最大寻址为32位,2^32 B=4 GB,指针的值就是在 0x00000000 - 0xFFFFFFFF 范围内的值。因此指针本身占用的内存数和它指向的数据类型没有任何关系。
  • 同理,64位编译模式下,理想的寻址位64位,也就是 2^64 B,这是个很大的值,而物理内存达不到这么大,CPU要实现64位的寻址能力只会增加系统复杂度和地址转换成本,因此Windows和Linux都做了限制,仅仅使用虚拟地址的48位,2^48 B=256TB。但是指针的占用内存字节数还是8 (只是Windows和Linux下,低48位有效而已).

额外讨论1:
那么,CPU寻址能力到底和什么有关呢?
答案是和地址总线的数量有关。

  • 16位CPU
    早期的CPU是16位的,一次能处理 16Bit(2个字节)的数据。这个时候计算机产业还处在早期,个人电脑也没有进入千家万户,也没有提出虚拟地址的概念,程序还是直接运行在物理内存上。典型的16位处理器是 Intel 8086,它的数据总线有16根,地址总线有20根,寻址能力为 2^20 B = 1MB
  • 32位CPU
    随着计算机产业的进步,出现了32位的CPU,一次能处理 32Bit(4个字节)的数据。这个时候就提出了虚拟地址的概念,并被应用到CPU和操作系统中,由它们共同完成虚拟地址和物理地址的映射。典型的32位处理器是 Intel 的 80386 和 Intel Pentium 4(奔腾4):80386 的数据总线和地址总线宽度都是32位,寻址能力达4GB;Pentium 4的地址总线宽度是36位,理论寻址能力达64GB。
  • 64位CPU
    现在64位的CPU也普及到千家万户,它们一次能处理64Bit(8个字节)的数据。典型的64位处理器是 Intel 的 Core i3、i5、i7 等,它们的地址总线宽度为 40~50 位左右。

值得注意的是,支持多大的寻址空间和CPU的位数没有直接关系,CPU的位数是指寄存器的位数,也可以说是数据总线的数量,衡量的是单次处理数据的能力。一般来说,地址总线会随着数据总线增多,也随之增多,用以支持更大的寻址空间。

额外讨论2:
short, int, long, long long在32位编译模式下和64编译模式下,占多少字节?
结论: 一样的!

short int long long long __int64
32位 2 4 4 8 8
64位 2 4 4 8 8

实验:

  • 64位
    C++的一个指针占内存几个字节?
  • 32位
    C++的一个指针占内存几个字节?