结构体的对齐规则
- 第一个成员在与结构体变量偏移量为0的地址处。
- 剩余成员变量要对齐到对齐数的整数倍的地址处。
- 对齐数:编译器默认对齐数与该成员大小的较小值
- vs中默认对齐数为8
- 没有默认对齐数,那么对齐数就是其本身成员大小
- 结构体总大小为最大对齐数的整数倍。
- 嵌套结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是最大对齐数(含嵌套结构体的对齐数)的整数倍。
例1:
#include <stdio.h>
struct s1 {
char c1;
int i;
char c2;
};
int main() {
printf("%d" , sizeof(struct s1));
return 0;
}
第一个成员 char c1
在结构体变量偏移 0地址
处开辟空间。第二个 int i
成员的大小是 4个字节
,vs默认对齐数是 8
两者取较小值是 4
,所以int i
成员要对齐到 4
的整数倍的地址处,中间的空间就浪费掉了。第三个成员 char c2
的大小是 1个字节
,与最大对齐数取较小值是 1
,char c2
成员对齐到 1
的整数倍的地址处。所有成员分配完之后,现在是 9个字节
,但是结构体的大小为最大对齐数的整数倍。成员中最大对齐数是 4个字节
,要对齐到 4字节
的整数倍,所以最终 struct s1
结构体大小是 12字节
。
修改默认对齐数
语法:
#pragma pack( number )
number
指定默认对齐的是多少
例2:
#include <stdio.h>
#pragma pack(8) // 设置默认对齐数为8
struct s1 {
char c1;
int i;
char c2;
};
#pragma pack() // 取消设置的默认对齐数,恢复默认
#pragma pack(1) // 设置默认对齐数为1
struct s2 {
char c1;
int i;
char c2;
};
#pragma pack() // 取消设置的默认对齐数,恢复默认
int main() {
printf("%d\n", sizeof(struct s1)); // 12
printf("%d", sizeof(struct s2)); // 6
return 0;
}
注:对齐数通常情况下设置为2的n次方。对齐数的不同,结构体的大小也可能不相同。