4

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

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),所以我很困惑为什么将四重像素分组会改变大小。我很在意,因为用 short 编写程序比使用 2 个无符号字符更容易,但是每个像素要花费 0.25 个字节。

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

提前感谢您的帮助。

4

3 回答 3

9

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

结构的对齐是其所有成员的最大对齐。对齐 1也是如此pix1,因为它只有字符,但pix2有来自短成员的对齐 2。then 的对齐pix4方式从pixels成员那里获取对齐方式,因此在第一种情况下为 1,在第二种情况下为 2。

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

这在所有平台上都是一样的。

于 2012-06-05T08:08:30.790 回答
2

是的,它与对齐有关。编译器希望在自然边界上对齐变量,因此 short 将是 16 位(2 字节)对齐的。因此,包含 short 的结构也将在 16 位边界上对齐。

于 2012-06-05T08:06:39.957 回答
1

在 Linux 32 位上也有同样的效果。

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

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

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

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

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

于 2012-06-05T08:05:27.103 回答