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

例如< p >: sizeof(char*)返回4。正如int*long long*,我已经尝试过的一切。有什么例外吗?< / p >
143517 次浏览

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

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

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

一般来说,当你在不同的平台上编译时,sizeof(几乎任何东西)都会改变。在32位平台上,指针的大小总是相同的。在其他平台上(64位是最明显的例子),这种情况可能会发生变化。

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

你得到的保证是sizeof(char) == 1。没有其他保证,包括不保证sizeof(int *) == sizeof(double *). c。

在实践中,指针的大小在16位系统上为2(如果您能找到一个),在32位系统上为4,在64位系统上为8,但是依赖于给定的大小并不能获得任何东西。

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

除了16位/32位/64位的差异之外,还会发生更奇怪的事情。

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

现在这是非常不寻常的,因为硬件设计师已经了解了字节可寻址性的价值。

只是已经发布的列表中的另一个例外。在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位段值组成

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

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

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

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

即使是在普通的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谈到了这个在这里

8位和16位指针用于大多数低规格微控制器。这意味着每一台洗衣机、微型电脑、冰箱、老式电视甚至汽车。

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

它是最新的,便宜的,每个人都可以使用,值得为之编程。

在windows 32位机器上的Turbo C编译器中,指针和int的大小为2字节。

所以指针的大小是编译器特定的。但一般大多数编译器实现为支持32位4字节指针变量和64位8字节指针变量)。

所以指针的大小在所有机器上都是不一样的。

指针的大小基本上取决于实现它的系统的体系结构。例如,在64位计算机中,32位指针的大小为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字节。

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

微软保留了LLP64,其中longlong = 64位宽,但long保留为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

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