结构体的对齐规则:
- 第一个成员在与结构体变量偏移量为0的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
- 结构体总大小为**最大对齐数(每个成员变量都有一个对齐数)的整数倍。
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。
VS中默认的值为8
Linux没有具体默认对齐数
结构体的内存对齐是拿空间来换取时间的做法。
那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:
让占用空间小的成员尽量集中在一起。
计算结构体的大小
#include<stdio.h>
typedef struct S
{
char a;
int i;
double b;
}S;
struct S2
{
double c;
char d;
int i;
};
struct S3
{
char e;
struct S2 s2;
int f;
};
int main()
{
S s;
struct S3 s3;
printf("%d\n", sizeof(s));//16
printf("%d\n", sizeof(s3));//32
return 0;
}
修改默认对齐数
用#pragma 这个预处理指令来改变默认对齐数
利用offsetof宏来计算结构体中某变量相对于首地址的偏移
用法:
offsetof(type,member)
#include<stdio.h>
#include<stddef.h>
#pragma pack(2)
//把默认对齐数改为2
struct S
{
char a;//0
//1
int i;//2-5
char b;//6
//7
};
#pragma pack()//恢复默认对齐数8
int main()
{
printf("%d\n", sizeof(struct S));
printf("%d\n", offsetof(struct S, a));
printf("%d\n", offsetof(struct S, i));
printf("%d\n", offsetof(struct S, b));
return 0;
}
运行结果: