结构体在内存中的大小计算不是数结构成员所占空间的总和,它有它的计算规则计算规则如下
1.结构体首成员要对齐到和结构体成员起始位置偏移量为0的地址
2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处
3.对齐数=编译器默认的对齐数与成员变量大小的最小值
注:VS中默认对齐数为8,Linux中gcc没有默认对齐数,对齐数就是该成员变量的大小
4.结构体总大小为最大对齐数(每个成员都有对齐数,所有对齐数中最大的)的整数倍
5.当结构体中嵌套了结构体,嵌套的结构体要对齐到自己结构体成员变量中最大的对齐数的整数倍处,这时,结构体总大小为最大对齐数的整数倍,包括嵌套结构体里面的.
上面说了这么多规则,可能脑子里面,还是不明白结构体大小是怎么计算的,别着急,看下面的代码(自己粘到编译器下,运行一下)
struct S1
{
char s1;
int i;
char s2;
};
struct S2
{
int i;
char s1;
char s2;
};
int mian()
{
printf("%zd\n",sizeof(struct S1));
printf("%zd\n",sizeof(struct S2)
return 0;
}
结构体里面放的类型相同,但是计算的结果不一样,这就要用到上面规则,我用下面的表格模拟在内存中的存储
s1的数据 | 0 |
1 | |
2 | |
3 | |
i 的数据 | 4 |
i 的数据 | 5 |
i 的数据 | 6 |
i 的数据 | 7 |
s2的数据 | 8 |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 |
先看第一个结构体,首成员变量为char s1,大小为1个字节,即在0的前面放s1,与0对齐对齐数即为1(我是在编译器为VS的情况下来说的),第二个成员变量为 int i 大小为4个字节,这时 i 的对齐数为4,也就是说 i 的数据要在4那个位置开始放数据,大小为4个字节,会占4个格子,最后一个也是一个char类型,占一个1格子,计算一下此时已经用了9个格子,也就是9个字节(中间没放数据的格子也算开辟的空间),但是结构体的总大小为最大对齐数的整数倍,同时还要比9大,因为12是4的倍数,且比9大,所以该结构体的大大小为12个字节.
这是第一个结构体大小的计算,可以仿照该方法计算出第二个的大小.
同样嵌套也是这个原理,可自行计算.