3

可能重复:
为什么结构的 sizeof 不等于每个成员的 sizeof 之和?

为什么sizeof();这个结构的 16 字节?我正在用 g++ 编译。

struct bitmapfileheader {       
     unsigned short bfType;
     unsigned int bfSize;
     unsigned short bfReserved1;
     unsigned short bfReserved2;
     unsigned int bfOffBits;   
   };
4

9 回答 9

12

这是因为 4 字节的 int 对齐到 4 字节的边界,所以 bfType 之后有 2 字节的填充。

于 2009-12-09T20:27:48.077 回答
8

结盟。 可能在您的平台上,整数必须是 4 字节对齐的,而短裤是 2 字节对齐的。

+0 -1 : bfType
+2 -3 : <padding>
+4 -7: bfSize
+8 -9: bfReserve1
+10 -11: bfReserve2
+12 -15: bfOffBits
-------------
16 bytes

对齐很好,因为未对齐的结构需要对许多架构进行额外的工作。

于 2009-12-09T20:28:04.473 回答
7

结构中的各个字段需要适当对齐。编译器将在结构中填充额外的空间以满足对齐要求。

如果你不想要这个,你可以使用UNALIGNED宏。

于 2009-12-09T20:27:30.810 回答
5

我认为您的编译器对字段使用 4 字节对齐。

于 2009-12-09T20:27:27.317 回答
2

这个问题是因为一个称为对齐的概念。在许多情况下,希望将一个数字放置在一个以字节为单位的数字大小的倍数的地址上(达到某个最大值,通常是平台的指针大小)。这样放置的变量被称为与n 字节边界对齐,其中n是数字。其确切效果取决于处理器。如果数据正确对齐,许多处理器会更快地执行数学运算。有些甚至无法对不合适对齐的数据执行操作(有时甚至是加载操作)——为了处理此类数据,必须将其加载到两个寄存器中,然后需要执行一系列位移和掩码以获得一个可用的值,然后它需要放回去。可以将其想象为将一半存储int在两个存储桶中的每个存储桶中,并且需要将它们放在一起才能使用它,而不是简单地将整个存储int在一个存储桶中。

在您的情况下,初始bfType可能需要与 2 字节边界bfSize对齐,而可能需要与 4 字节边界对齐。编译器必须通过将整个结构对齐到 4 个字节并在bfType和之间留下 2 个未使用的字节来适应这一点bfSize

但是,在同一系统上编译时,填充可能会保持一致,这可能取决于编译器选项和使用的特定 ABI(通常,除非您试图使事情不兼容,否则您在同一平台上是安全的)。您可以自由地创建具有相同前 5 个成员的另一个结构,它们将在完全相同的位置占用另一个结构的 16 个字节。

如果你真的需要避免这种行为,你将不得不检查你的编译器文档。大多数编译器都提供了一个属性或关键字来声明一个变量没有对齐,而另一个则表明一个结构不应该有填充。但在一般情况下,这些很少是必要的。

于 2009-12-09T20:45:03.450 回答
1

你可以pragma打包结构以避免填充

于 2009-12-09T20:33:35.420 回答
1

ISO C++03, 9.2[class.mem]/12:

分配没有中间访问说明符的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址。由访问说明符分隔的非静态数据成员的分配顺序未指定 (11.1)。实现对齐要求可能会导致两个相邻的成员不能立即分配;管理虚拟功能 (10.3) 和虚拟基类 (10.1) 的空间要求也是如此。

于 2009-12-09T20:37:26.967 回答
0

由于分配内存的方式,短时间后会有填充

于 2009-12-09T20:28:20.093 回答
0

这是由于对齐 - 编译器必须做一些填充。

于 2009-12-09T20:29:37.610 回答