Windows 64位结构大小因包含的数据类型而异?

时间:2012-06-05 07:57:25

标签: c++ struct sizeof short

我有两个不同的数据结构,原则上应该具有相同的大小,我想知道它们为什么不这样做。

struct pix1 { 
    unsigned char r; 
    unsigned char g;
    unsigned char b; 
    unsigned char a; 
    unsigned char y[2]; 
 }; 

struct pix2 { 
    unsigned char r; 
    unsigned char g;
    unsigned char b; 
    unsigned char a; 
    unsigned short y; 
 }; 

然后,我将这些像素中的四个组合在一起,如下:

struct pix4 {
    pix1 pixels[4]; // or pix2 pixels[4]
    unsigned char mask;
};

...但事实证明,根据sizeof(pix4),这种分组的大小会发生变化,具体取决于我是使用pix1还是pix2。个别sizeof(pix1)== sizeof(pix2),所以我很困惑为什么分组四像素会改变大小。我关心的是因为用2个无符号字符来编写带有短路的程序比较容易,但是每个像素耗费我0.25个字节。

我不确定这个架构是否具体,因为我没有在其他类型的机器上测试过。它可以对齐吗?这是我需要担心的事情,还是我可以继续进行简短的实施?

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:9)

结构的大小是相同的,但它们的对齐要求是不同的。

结构的对齐是其所有成员的最大对齐。因此pix1具有对齐1,因为它只有字符,但pix2具有来自短成员的对齐2。然后pix4的对齐从pixels成员获得对齐,因此在第一个中它是1,在第二个中是2。

现在要确保数组的所有成员都正确对齐,结构的大小会向上舍入到其对齐的下一个倍数。在这两种情况下,pixels的大小为24,但是有1个字节mask。在第一种情况下,对齐是1,因此25是它的倍数,sizeof(pix4)是25,但在第二种情况下,对齐是2,因此sizeof(pix4)必须向上舍入到下一个偶数,26

所有平台都是如此。

答案 1 :(得分:2)

是的,它与对齐有关。编译器想要在natural boundaries上对齐变量,因此短路将是16位(2字节)对齐。因此,包含short的结构也将在16位边界上对齐。

答案 2 :(得分:1)

同样的效果在Linux 32位上。

出于对齐原因,它与填充有关。

如果您使用struct pix1,则只有字符,因此struct pix4可以保留原样。但是如果你使用struct pix2,它包含一个简短的。因此,整个结构必须对齐,即使在struct pix4数组中,每个元素都会对齐,以便对y进行干净访问。

更详细:带有2个元素的strict pix4数组的形状如下:

                +-----     [0]     -----+++-----    [1]     -----+
First version:  rgbayyrgbayyrgbayyrgbayyMrgbayyrgbayyrgbayyrgbayyM
Second version: rgbayyrgbayyrgbayyrgbayyM rgbayyrgbayyrgbayyrgbayyM
                ---------25--------------+ <- +1

为什么呢?因为--- ed部分是25个字节,这是一个奇数。对于第一个版本来说这没问题 - 第二个元素可以很高兴地从一个奇数地址开始 - 但是对于第二个版本。 yy必须始终位于偶数(对齐)地址上,因此struct pix4为26个字节。