sizeof(某些指针)总是等于4吗?

时间:2008-12-29 23:03:23

标签: c++ c pointers memory sizeof

例如: sizeof(char*)返回4. int*long long*和我尝试过的所有内容一样。这有什么例外吗?

17 个答案:

答案 0 :(得分:178)

您获得的保证是sizeof(char) == 1。没有其他保证,包括不保证sizeof(int *) == sizeof(double *)

实际上,指针在16位系统上的大小为2(如果你能找到一个),在32位系统上是4,在64位系统上是8,但在依赖中没有什么可以获得的在给定的大小。

答案 1 :(得分:36)

即使在普通的x86 32位平台上,您也可以获得各种指针大小,试试这个例子:

struct A {};

struct B : virtual public A {};

struct C {};

struct D : public A, public C {};

int main()
{
    cout << "A:" << sizeof(void (A::*)()) << endl;
    cout << "B:" << sizeof(void (B::*)()) << endl;
    cout << "D:" << sizeof(void (D::*)()) << endl;
}

在Visual C ++ 2008下,对于指向成员函数的指针大小,我得到4,12和8。

Raymond Chen谈到了here

答案 2 :(得分:29)

已发布列表的另一个例外。在32位平台上,指针可以取6,不是4 ,字节:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char far* ptr; // note that this is a far pointer
    printf( "%d\n", sizeof( ptr));
    return EXIT_SUCCESS;
}

如果你使用Open Watcom编译这个程序并运行它,你会得到6,因为它支持的远指针包括32位偏移和16位段值

答案 3 :(得分:24)

如果您正在为64位计算机进行编译,那么它可能是8。

答案 4 :(得分:17)

从技术上讲,C标准只保证sizeof(char)== 1,其余的由实现决定。但在现代x86架构(例如Intel / AMD芯片)上,它是相当可预测的。

您可能听说过处理器被描述为16位,32位,64位等。这通常意味着处理器使用N位作为整数。由于指针存储内存地址,而内存地址是整数,因此这有效地告诉您将使用多少位作为指针。 sizeof通常以字节为单位,因此为32位处理器编译的代码将报告指针的大小为4(每字节32位/ 8位),64位处理器的代码将报告指针的大小为8 (每字节64位/ 8位)。这就是32位处理器4GB RAM的限制来自 - 如果每个存储器地址对应一个字节,为了满足更多存储器需要大于32位的整数。

答案 5 :(得分:6)

指针的大小主要取决于实现它的系统的体系结构。例如,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个字节。

答案 6 :(得分:6)

除了16/32/64位差异外,甚至可能发生更奇怪的事情。

有些机器的sizeof(int *)将是一个值,可能是4,但sizeof(char *)更大。自然地处理单词而不是字节的机器必须“扩充”字符指针,以指定您真正想要的单词部分,以便正确实现C / C ++标准。

现在这很不寻常,因为硬件设计人员已经学会了字节寻址的价值。

答案 7 :(得分:5)

大多数低调微控制器都使用8位和16位指针。这意味着每台洗衣机,微型冰箱,冰箱,旧电视机,甚至汽车。

你可以说这些与现实世界的编程无关。 但这是一个现实世界的例子: Arduino具有1-2-4k ram(取决于芯片),带有2个字节的指针。

它是最近的,价格便宜,适合每个人,值得编码。

答案 8 :(得分:4)

除了人们对64位(或其他)系统所说的内容之外,还有其他类型的指针而不是指向对象的指针。

指向成员的指针几乎可以是任何大小,具体取决于编译器如何实现它们:它们的大小不一定相同。尝试指向POD类的成员指针,然后尝试从具有多个基类的类的基类之一继承的指向成员的指针。真有趣。

答案 9 :(得分:3)

据我所知,它基于内存地址的大小。因此,在具有32位地址方案的系统上,sizeof将返回4,因为那是4个字节。

答案 10 :(得分:3)

指针和int的大小在Windows 32位机器上的Turbo C编译器中是2个字节。

因此指针的大小是编译器特定的。但通常大多数编译器都支持32位的4字节指针变量和64位机器的8字节指针变量。

因此指针的大小在所有机器中都不相同。

答案 11 :(得分:3)

不,指针的大小可能因架构而异。有很多例外。

答案 12 :(得分:3)

通常,在不同平台上编译时,sizeof(几乎任何东西)都会发生变化。在32位平台上,指针总是相同的大小。在其他平台上(64位是明显的例子),这可能会改变。

答案 13 :(得分:2)

Win64(Cygwin GCC 5.4)中,让我们看看下面的例子:

首先,测试以下结构:

struct list_node{
    int a;
    list_node* prev;
    list_node* next;
};

struct test_struc{
    char a, b;
};

测试代码如下:

std::cout<<"sizeof(int):            "<<sizeof(int)<<std::endl;
std::cout<<"sizeof(int*):           "<<sizeof(int*)<<std::endl;
std::cout<<std::endl;

std::cout<<"sizeof(double):         "<<sizeof(double)<<std::endl;
std::cout<<"sizeof(double*):        "<<sizeof(double*)<<std::endl;
std::cout<<std::endl;

std::cout<<"sizeof(list_node):      "<<sizeof(list_node)<<std::endl;
std::cout<<"sizeof(list_node*):     "<<sizeof(list_node*)<<std::endl;
std::cout<<std::endl;

std::cout<<"sizeof(test_struc):     "<<sizeof(test_struc)<<std::endl;
std::cout<<"sizeof(test_struc*):    "<<sizeof(test_struc*)<<std::endl;    

输出如下:

sizeof(int):            4
sizeof(int*):           8

sizeof(double):         8
sizeof(double*):        8

sizeof(list_node):      24
sizeof(list_node*):     8

sizeof(test_struc):     2
sizeof(test_struc*):    8

您可以看到,在64位中,sizeof(pointer)8

答案 14 :(得分:1)

指针只是地址的容器。在32位机器上,您的地址范围是32位,因此指针总是4个字节。在64位机器上,你有一个64位的地址范围,一个指针将是8个字节。

答案 15 :(得分:1)

指针大小为4个字节的原因是因为您正在编译32位体系结构。正如FryGuy指出的那样,在64位架构上你会看到8。

答案 16 :(得分:0)

仅仅为了完整性和历史性的兴趣,在64位世界中,长和长类型的大小有不同的平台约定,名为LLP64和LP64,主要在Unix类型系统和Windows之间。一个名为ILP64的旧标准也使int = 64位宽。

Microsoft维护LLP64,其中longlong = 64位宽,但长期保持在32位,以便于移植。

Type           ILP64   LP64   LLP64
char              8      8       8
short            16     16      16
int              64     32      32
long             64     64      32
long long        64     64      64
pointer          64     64      64

来源:https://stackoverflow.com/a/384672/48026