结构体的大小超出预期。

3

我已经阅读了这个问题:C++中的结构填充 和 这个问题 为什么对于一个结构体,sizeof不等于每个成员变量的sizeof之和?

虽然我知道这并非标准,但我认为这是一个合理的问题。

为什么在x64系统上这个结构体的大小是16?

struct foo { char* b; char a;};

有效大小应该是8 + 1 = 9,但我知道有填充物参与其中。不管怎样,我认为 'a' 只会被填充到达到 'int' 的大小,即其他3个字节共计12个字节。
有没有任何特定编译器(gcc)认为它应该具有16个字节的大小的原因?
猜测:最大类型(例如double或在这种情况下的x64指针)是否会决定要使用的填充?

1
这是一个我们实际上无法回答的实现细节。 - NathanOliver
你读了第一个答案的第一句话吗:“这是因为添加了填充以满足对齐约束。” - Bo Persson
2个回答

11

很可能编译器将结构体对齐在8字节的边界上,以提高访问速度。结构体大小为9可能会通过未对齐访问而大大减慢CPU速度(另外,栈指针不应该位于奇数地址)。大小为12(3个填充字节)可以正常工作,但某些操作(如FPU操作)更喜欢8或16字节的对齐方式。


1
这是由于内存对齐的原因。默认情况下,内存未按一字节顺序对齐,因此会出现这种情况。在32位系统中,内存按4字节块分配。
您可以通过在定义结构时设置__attribute__((packed, aligned(x)))来更改此行为。通过这种方法,内存将按x字节块分配。

问题:在 x64 系统中,它是以 8 字节为单位分配的吗? - Dean
动态分配的内存具有适用于任何类型的对齐方式,实际上意味着最严格的类型。在 x86_64 上,指针应该是 8 字节对齐的,因此动态分配的内存应该至少是 8 字节对齐的。 - Useless
据我所知,x86_64的内存对齐也是4字节,但对于堆栈边界以及如Useless所提到的指针,它是8字节。 - AKJ88

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接