2009-12-09 32 views
3

可能重复:
Why isn’t sizeof for a struct equal to the sum of sizeof of each member?C++结构尺寸:2 + 4 + 2 + 2 + 4 = 16

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

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

Dupe:http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member – 2009-12-09 20:29:41

+1

http:///en.wikipedia.org/wiki/Sizeof#Structure_padding – 2009-12-09 20:29:56

+1

谁说short是2而int是4? – 2009-12-09 20:35:53

回答

5

我认为你的编译器对字段使用4字节的allignment。

+0

只有'int'字段。 – Zooba 2009-12-09 20:30:04

7

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

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

+6

我不认为'unaligned'是一个关键字。这将是编译器特定的。 – GManNickG 2009-12-09 20:29:04

+1

答案很好,但'unaligned'不是C++关键字。 – coppro 2009-12-09 20:29:25

+0

具体来说,在这种情况下,它看起来像在第一个“int”之前填充2个字节,以将其与4字节边界对齐。短裤对齐到2个字节的边界。 – 2009-12-09 20:31:26

12

这是因为4字节整数与4字节边界对齐,所以在bfType之后有2个字节的填充。

8

对齐。 可能在您的平台上,int必须是4byte对齐,并且shorts是2byte对齐。

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

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

0

因为内存的方式分配,会有一个短暂

+1

确实,这是一个很好的建议。但是,这里的应用程序涉及处理.bmp文件,所以这不是一个选项。 +1无论如何;-) – 2009-12-09 20:34:40

0

这之后填充是由于定位 - 编译器必须做一些填充。

1

U可以编译包装结构,以避免填充

1

ISO C++ 03,9.2 [class.mem]/12:(非联合)的

非静态数据成员声明的类没有介入的访问说明符被分配,以便后面的成员在类对象内有更高的地址。未指定由访问说明符分隔的非静态数据成员的分配顺序(11.1)。 执行对齐需求可能会导致两个相邻成员不能立即被分配;所以可能需要管理虚拟功能(10.3)和虚拟基类(10.1)的空间。

2

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

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

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

如果你真的需要避免这种行为,你将不得不检查你的编译器文档。大多数编译器提供一个属性或关键字来声明一个变量没有对齐,另一个指示一个结构不应该有填充。但这些在事物的一般过程中很少需要。