【问题标题】:What is the size of a pointer?指针的大小是多少?
【发布时间】:2011-10-08 18:25:28
【问题描述】:

指针的大小是否与其指向的类型的大小相同,还是指针总是具有固定大小?比如……

int x = 10;
int * xPtr = &x;
char y = 'a';
char * yPtr = &y;

std::cout << sizeof(x) << "\n";
std::cout << sizeof(xPtr) << "\n";
std::cout << sizeof(y) << "\n";
std::cout << sizeof(yPtr) << "\n";

这个输出会是什么? sizeof(xPtr) 会返回 4,sizeof(yPtr) 会返回 1,还是这 2 个指针实际上会返回相同的大小?我问这个的原因是因为指针存储的是内存地址,而不是它们各自存储地址的值。

【问题讨论】:

    标签: c++ pointers sizeof


    【解决方案1】:

    函数指针可以有非常不同的大小,在 X86 机器上从 4 到 20 字节,具体取决于编译器。所以答案是否定的 - 尺寸可能会有所不同。

    另一个例子:以 8051 程序为例,它具有三个内存范围,因此具有三种不同的指针大小,从 8 位、16 位、24 位,这取决于目标所在的位置,即使目标的大小始终相同(例如字符)。

    【讨论】:

    • 这仅适用于您查看程序集的情况。在 C++ 中,不同的大小从您的视图中隐藏。
    • @Jay:一点也不真实。 sizeof(p)可以针对不同类型的指针给出不同的结果。
    • 对不起,我不是很清楚和具体。在特定的 x86 机器上,指针大小不会改变。在不同的架构或编译器上,指针大小可能不同。非常小心地使用“变化”的严格定义。
    • @Jay 指向成员函数的指针可以在转换时改变其大小 (Pointers to member functions are very strange animals)。
    • @Jay 这不是 MSC 特定的:所有支持多重继承的 C++ 编译器都必须在调用成员函数指针时调整对象指针,从而提供适当的工具来在运行时计算正确的偏移量.许多编译器通过保存所需信息的结构来实现成员函数指针。我知道的唯一例外是 Digital Mars:它会生成一个执行对象指针调整的 thunk,而成员函数指针则指向此存根代码。这允许 所有 指针大小相同。
    【解决方案2】:

    指针通常具有固定大小,例如。在 32 位可执行文件上,它们通常是 32 位的。有一些例外,比如在旧的 16 位窗口上,当您必须区分 32 位指针和 16 位指针时……通常可以很安全地假设它们在现代桌面操作系统上的给定可执行文件中是统一的.

    编辑:即便如此,我强烈警告不要在您的代码中做出这种假设。如果你要写的东西绝对必须有一定大小的指针,你最好检查一下!

    函数指针是另一回事——有关更多信息,请参阅Jens' answer

    【讨论】:

    • @cf16 他们可以,但我的回答只是断言,对于现代桌面操作系统,即 Win32/64、Linux……你能给我举个例子说明它在其中一个系统上的不同吗?跨度>
    • 你自己提到了一些例外,例如,但是好的
    • @cf16 不想让你关机 :) 你知道 Windows 7 有什么例外吗?
    • 一个一般的例子,windows,是的,我认识这个人。我指的是near/far pointers
    • @4pie0 您提供的链接并不表明在 C 中,这些指针的大小会有所不同。
    【解决方案3】:

    在 32 位机器上指针大小为 32 位(4 字节),而在 64 位机器上为 8 字节。无论它们指向什么数据类型,它们的大小都是固定的。

    【讨论】:

    • 在 64 位机器上的 32 位可执行文件怎么样?
    • 它也是 32 位的。 @Ident
    • @Ident 为什么你认为“32 位在 64 位机器上可执行,指针是 32 位”是错误的?我刚刚在我的 64 位 Ubunut 上编译了一个 32 位 C 程序,sizeof 输出是 4 个字节。
    • @Rick 它是关于它被编译的字大小,而不是关于它运行的机器,所以如果它被编译为 32 位,那么它将在 64 机器上为 32 位,这使得原来的答案不正确。
    【解决方案4】:

    回答您的其他问题。指针的大小和它所指向的大小无关。一个很好的类比是将它们视为邮政地址。房子地址的大小与房子的大小没有关系。

    【讨论】:

    • 但是邮政编码在不同的地区可以有不同的大小,见Are all data pointers of the same size。指向不同类型的指针可以有不同的大小存在某种关系。
    • 如果您查看 CPU,就会发现有不同种类的寻址方法(取决于处理器)。最小的编码相对于指令所在位置的地址,而不是给出绝对地址。有些是相对于 CPU 寄存器的。它们比第一种类型大一点(如果您包括寄存器)。最大的有一个绝对地址。这些通常是最大的,因为它们需要有足够的位来编码整个处理器地址空间。 C 和 C++ 对您隐藏了这些细节。你使用绝对地址,编译器决定它如何得到你想要的。
    【解决方案5】:

    指针在同一架构上的大小并不总是相同。

    您可以阅读更多关于“near”、“far”和“huge”指针的概念,这只是指针大小不同的示例......

    http://en.wikipedia.org/wiki/Intel_Memory_Model#Pointer_sizes

    【讨论】:

      【解决方案6】:

      它们在字寻址机器(例如 Cray PVP 系统)上可能不同。

      当今的大多数计算机都是可字节寻址的机器,其中每个地址指的是一个字节的内存。在那里,所有的数据指针通常都是相同的大小,即机器地址的大小。

      在字可寻址机器上,每个机器地址都指向一个大于字节的字。在这些情况下,指向内存字节的 (char *) 或 (void *) 指针必须同时包含字地址和地址字内的字节偏移量。

      http://docs.cray.com/books/004-2179-001/html-004-2179-001/rvc5mrwh.html

      【讨论】:

        【解决方案7】:

        指针的大小是系统保存唯一内存地址所需的大小(因为指针只保存它指向的地址)

        【讨论】:

        • 除非指向诸如字地址机器上的字符之类的东西。
        【解决方案8】:

        最近遇到了一个不正确的情况,TI C28x 板可以有一个 sizeof 指针 == 1,因为这些板的一个字节是 16 位,而指针大小是 16 位。更令人困惑的是,它们还有 22 位 的远指针。我不太确定远指针的 sizeof 是多少。

        一般来说,DSP 板的整数大小可能很奇怪。

        因此,如果您在奇怪的地方寻找,那么 2020 年的指针大小仍然会很奇怪

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-10
          • 1970-01-01
          • 2014-06-04
          • 1970-01-01
          • 2014-06-17
          相关资源
          最近更新 更多