当编译器决定填充结构时

时间:2014-04-24 14:19:42

标签: c++ c struct sizeof

让我们说:

struct A{
    char a1;
    char a2;
};

struct B{
    int b1;
    char b2;
};

struct C{
    char C1;
    int C2;
};

我知道因为填充到字长的倍数(假设字大小= 4),sizeof(C)==8虽然sizeof(char)==1sizeof(int)==4

我希望sizeof(B)==5代替sizeof(B)==8

但如果sizeof(B)==8我希望sizeof(A)==4代替sizeof(A)==2

有人可以解释为什么填充和对齐在这些情况下的工作方式不同吗?

3 个答案:

答案 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,那就是你所拥有的。