假如我们在vs的环境下来求sizeof(struct B)
struct B
{
int a;
short b;
char c;
int d;
};
在不知道结构体类型的存储方式时,我们会认为他的大小为两个int类型,加上一个short类型和一个char类型,即4+4+2+1共11个字节。但是我们运行起来可以看到,这个struct B的大小为12个字节。
至于为什么会产生这样的结果,我们首先要知道结构体的对齐规则。这里我们先创建一个结构体struct B b,第一个成员所在的位置偏移量就为0。我们先将int类型存入,占4个字节,再将short类型和char类型以及最后的int类型存入,但是实际上他并不是这样存的,而是在char类型存入后,有1个字节被浪费。(图片中蓝色位置)
产生这种情况的原因就是结构体对齐的另一个规则:其他成员要对起到对齐数的整数倍地址处(对齐数=编辑器默认的对齐数与该成员大小二者的较小值)。这里int的对齐数为4,所以应存到4的倍数,即偏移量为8的位置。因此这个结构体占12个字节的位置。
struct A
{
int a;
short b;
int c;
char d;
};
我们再来看这段代码,他的大小为16个字节,而产生这个结果的原因就是结构体对齐的第三个规则:结构体总大小为最大对齐数的整数倍,这里最大对齐数为4所以应占13个字节的结构体占了16个字节。
struct s1
{
double d;
char c;
int i;
};
struct s2
{
char c;
struct s1 b;
double d;
};
我们再来看这段代码,s2的大小为32个字节 。很明显的s2中嵌套了一个s1,它的对齐数为8,而这就是结构体对齐的最后一个规则:嵌套的结构体对齐到自己最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。