让我们看看下面两个代码:
struct S1
{
char c1;//1
int i;//4
char c2;//1
};
struct S2
{
char c1;//1
char c2;//1
int i;//4
};
int main()
{
struct S1 s1 = { 0 };
printf("%d\n", sizeof(struct S1));
printf("%d\n", sizeof(s1));
printf("%d\n", sizeof(struct S2));
system("pause");
return 0;
}
得出的结果会不会是一样的呢?
让我们看下结果:
答案是否定的。
造成这样的原因是:结构体对齐
结构体对齐的规则:
- 1.第一个成员在与结构体偏移量为0的地质处
- 2.其他成员变量要对其到某个数字(对其数)的整数倍的地址处
对齐数=编译器默认的一个对齐数与该成员大小的较小值(vs下为8, linux下为4) - 3.结构体总大小为最大对齐数(每个成员都有一个对齐数)的整数倍
- 4.如果出现嵌套情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
对齐规则如下图:共占12个字节
关于3 和 4规则 的运用:
struct S3
{
double d;//0- 7
char c;//8
//8-11被占用
int i;//12-15
};//16
struct S4
{
char c1;//0
//占用0-7
struct S3 s3;
//占用8 - 23
double d;//23 - 31
};//总计32
printf("%d\n", sizeof(struct S3));
printf("%d\n", sizeof(struct S4));
printf("%d\n", offsetof(struct S4, c1));
printf("%d\n", offsetof(struct S4, s3));
printf("%d\n", offsetof(struct S4, d));
结果
为什么存在对其?
1.平台原理(移植问题):不是所有硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出异常
2.性能问题:数据结构应该尽可能的在自然边界上对齐。原因在于,为了访问未对对齐的内存,处理器需要两次内存访问,而对齐的只需要一次