我有两个不同的数据结构,原则上应该具有相同的大小,我想知道它们为什么不这样做。
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个字节。
我不确定这个架构是否具体,因为我没有在其他类型的机器上测试过。它可以对齐吗?这是我需要担心的事情,还是我可以继续进行简短的实施?
提前感谢您的帮助。
答案 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个字节。