让我们说:
struct A{
char a1;
char a2;
};
struct B{
int b1;
char b2;
};
struct C{
char C1;
int C2;
};
我知道因为填充到字长的倍数(假设字大小= 4),sizeof(C)==8
虽然sizeof(char)==1
和sizeof(int)==4
。
我希望sizeof(B)==5
代替sizeof(B)==8
。
但如果sizeof(B)==8
我希望sizeof(A)==4
代替sizeof(A)==2
。
有人可以解释为什么填充和对齐在这些情况下的工作方式不同吗?
答案 0 :(得分:4)
常见的填充方案是填充结构,以便每个成员以该成员大小的偶数倍或机器字大小(以较小者为准)开始。整个结构按照相同的规则填充。
假设我期望这样的填充方案:
struct A
中最大的成员大小为1,因此不使用填充。
在struct B
中,将5的大小填充为8,因为一个成员的大小为4。
布局将是:
int 4
char 1
padding 3
在struct C
中,在int
之前插入一些填充,以便从可被4整除的地址开始。
布局将是:
char 1
padding 3
int 4
答案 1 :(得分:3)
由编译器决定如何最好地填充结构。出于某种原因,它决定在结构B中char b2在4字节边界上更优化地对齐。此外,特定体系结构可能具有编译器在决定如何填充结构时所考虑的要求/行为。
如果你打包'结构,然后你会看到你期望的大小(虽然这不是可移植的,可能会有性能损失和其他问题,具体取决于架构)。
答案 2 :(得分:1)
结构通常将根据包含的最大类型与边界对齐。考虑一个struct B myarray[5];
struct B
必须与8个字节对齐,以便它的b1成员始终在4字节边界上。 myarray[1].b1
无法从数组的第6个字节开始,如果sizeof(B)== 5,那就是你所拥有的。