为什么sizeof运算符返回的结构大小大于结构成员的总大小?


当前回答

除了其他答案,结构可以(但通常不)具有虚拟函数,在这种情况下,结构的大小还将包括vtbl的空间。

其他回答

C语言为编译器提供了一些关于内存中结构元素位置的自由:

内存孔可能出现在任意两个组件之间以及最后一个组件之后。这是由于目标计算机上的某些类型的对象可能受到寻址边界的限制sizeof运算符的结果中包含“内存孔”大小。sizeof仅不包括灵活数组的大小,灵活数组在C/C中可用++该语言的一些实现允许您通过pragma和编译器选项控制结构的内存布局

C语言为程序员提供了结构中元素布局的一些保证:

编译器需要分配一系列增加内存地址的组件第一个组件的地址与结构的起始地址一致未命名的位字段可以包括在结构中,以实现相邻元素的所需地址对齐

与元素对齐相关的问题:

不同的计算机以不同的方式排列对象的边缘位字段宽度的不同限制计算机在如何存储一个字中的字节方面存在差异(Intel 80x86和Motorola 68000)

对齐方式:

结构所占据的体积被计算为这样的结构阵列中对齐的单个元素的大小。结构应以便下一个后续结构的第一个元素不违反对齐要求

p.s更多详细信息可在此处获得:“塞缪尔·p·哈比森,盖伊·L·斯蒂尔C A参考,(5.6.2-5.6.7)”

除了其他答案,结构可以(但通常不)具有虚拟函数,在这种情况下,结构的大小还将包括vtbl的空间。

例如,如果您希望结构具有GCC的特定大小,请使用__attribute__((打包))。

在Windows上,使用带有/Zp选项的cl.exe编译器时,可以将对齐设置为一个字节。

通常,CPU更容易访问4(或8)的倍数的数据,这取决于平台和编译器。

所以这基本上是一个对齐问题。

你需要有充分的理由来改变它。

这可能是由于字节对齐和填充,使得结构在您的平台上达到偶数字节(或单词)。例如,在Linux上的C中,以下3种结构:

#include "stdio.h"


struct oneInt {
  int x;
};

struct twoInts {
  int x;
  int y;
};

struct someBits {
  int x:2;
  int y:6;
};


int main (int argc, char** argv) {
  printf("oneInt=%zu\n",sizeof(struct oneInt));
  printf("twoInts=%zu\n",sizeof(struct twoInts));
  printf("someBits=%zu\n",sizeof(struct someBits));
  return 0;
}

成员的大小(以字节为单位)分别为4字节(32位)、8字节(2x 32位)和1字节(2+6位)。上面的程序(在使用gcc的Linux上)将大小打印为4、8和4,其中最后一个结构填充为一个单词(在我的32位平台上为4 x 8位字节)。

oneInt=4
twoInts=8
someBits=4

上面给出了很多信息(解释)。

我只想分享一些方法来解决这个问题。

您可以通过添加pragma pack来避免它

#pragma pack(push, 1)

// your structure

#pragma pack(pop)