【问题标题】:How many bytes do pointers take up?指针占用多少字节?
【发布时间】:2014-01-12 20:34:09
【问题描述】:

我对指针以及它们占用多少字节有点困惑。在我的教科书中,它首先说 16 位系统上的指针占用 2 个字节,32 位系统占用 4 个字节,64 位系统占用 8 个字节等等。然后 10 行之后,它说指针占用了保存地址所需的那么多字节。这是我的问题:

  1. 这是否意味着如果我们假设在 64 位系统上,地址最多需要 8 个字节?
  2. 如果我们在 16 位系统上并且指针占用 2 个字节,而地址需要更多的 2 个字节来放置,那么会发生什么?

【问题讨论】:

标签: c pointers


【解决方案1】:

没有固定的答案;它完全取决于架构、编译器实现,甚至指针本身的类型。不保证指向不同类型的指针具有相同的大小和/或表示形式。

例如,假设一个字寻址架构,其中最小的可寻址存储单元是 16 位宽(或更宽)。每个单词可以包含多个char 值;所有其他类型占用一个完整的单词或更多。在这样的架构上,与其他指针类型相比,char * 和 void * 需要一些额外的位来偏移到字中。

还要注意,指针类型可能宽比存储地址实际所需的位数。最初的 Macintosh 在 Motorola 68000 CPU 上运行,它有 32 位字长,但地址总线上只有 24 位。指针类型为 32 位宽,高 8 位未使用。进取的 MacOS 程序员利用这一点将一些数据存储到指针类型的最高字节,充分利用了宝贵的 128 KB RAM。当然,摩托罗拉最终发布了具有 32 个地址线的 CPU(68020),这意味着所有代码都必须重写。

在现代商用台式机和服务器硬件(阅读:x86)上,假设所有指针类型的大小与本机字大小(32 位或 64 位)相同,并且所有指针类型都具有相同的大小和表示。请注意,这并不必须为真。

【讨论】:

    【解决方案2】:

    简短的回答是视情况而定。当我们说系统是 32 位时,这可能意味着本机整数是 32 位宽,本机地址(即指针大小)是 32 位宽,或两者兼而有之。

    除此之外,并非每个架构都使用flat memory model(例如,请参阅x86 memory segmentation)。这使事情变得更加复杂。

    最好将指针的大小视为不透明。

    C99 以intptr_t and uintptr_t 类型的形式提供工具,它们是保证足够宽以容纳指针的整数。

    【讨论】:

      【解决方案3】:

      指针的大小基本上取决于实现它的系统架构。例如,32 位指针的大小在 64 位机器中为 4 字节(32 位)和 8 字节(64 位)。机器中的位类型只不过是它可以保存的内存地址。 32 位机器可以保存2^32,64 位机器可以保存2^64 地址空间。因此,指针(指向内存位置的变量)应该能够指向机器拥有的任何内存地址 (2^32 for 32 bit and 2^64 for 64 bit)。

      由于这个原因,我们看到指针的大小在 32 位机器中为 4 字节,在 64 位机器中为 8 字节。

      已回复Is the sizeof(some pointer) always equal to four?

      【讨论】:

        【解决方案4】:

        指针用于存储变量的地址。内存地址/位置的宽度取决于计算机架构。如果计算机架构是 16 位,则意味着它可以有 2^16 个内存位置。因此,对于能够在这台计算机中存储任何内存位置的指针,它应该是 16 位宽,即 2 字节(8 位 = 1 字节)。同样,对于 32 位和 64 位架构,我们需要分别具有大小为 4 字节(32 位宽)和 8 字节(64 位宽)的指针。
        此外,如果系统是 16 位,那么它的地址位置不能超过 16 位。

        【讨论】:

          【解决方案5】:

          这将告诉您在系统上表示一个指针需要多少字节。

              #include <stdio.h>
              int main() {
                  printf("%ld bytes per pointer\n", sizeof(void *));
              }
          

          这是一个您可以使用的编译器标志:

          $ gcc -m32 -o prog32 prog.c
          $ gcc -m64 -o prog64 prog.c
          

          第一行为 32 位环境生成一个二进制文件,为您提供 4 个字节的指针。第二行为 64 位环境生成一个二进制文件,为您提供 8 个字节的指针。您可以通过运行上述程序来确认这一点。

          假设,您使用的是 GCC 的 64 位系统。希望这能澄清一点。

          【讨论】:

          • 指针持有地址,它们本身也有地址,所以不是一回事。 16 位系统也可以有超过 64K 的内存,所以你的第二个陈述是错误的。
          • @MarkTolonen,是的,好点。我的意图是引导@GovernmentFX 摆脱 “指针占用 2 个字节,而地址需要更多 2 个字节。” 这就是我的意思,“指针 是 b> 地址,仅此而已。”例如,为了指向int,只需要一个指针。 那是地址。不过谢谢,因为 OP 还应该明白,一个地址到一个地址到一个地址,等等。
          • @MarkTolonen,是的,可以超越 C 语言功能,使用库或其他技术来处理 16 位系统上的任意数量的内存。但是,我将此问题的上下文视为纯 C 和指针问题,因为这就是它的标记。我坚持我的说法,即使用 16 位地址,可以在 C 中寻址 2^16 字节的内存。现在离圣诞节太近了,所以我承认,我已经编辑了我的答案,以保持它的简单性,希望 OP 能够更多地了解指针的存储方式以及他如何验证这一点,动手操作。干杯。 :-)
          猜你喜欢
          • 2019-09-25
          • 1970-01-01
          • 1970-01-01
          • 2018-11-06
          • 2022-11-24
          • 2018-09-07
          • 2012-03-12
          • 2012-12-21
          • 2023-03-16
          相关资源
          最近更新 更多