结构体大小的计算
在计算结构体大小之前,我们必须知道一个概念,那就是对齐数。
几乎每个编译器都有一个对齐数,不同的编译器默认的对齐数不同,VS中的对齐数默认为8。(也可以自己调节对齐数)
规则
- 第一个成员在与结构体变量偏移量为0的地址处
- 其他成员变量要对齐到某个数字(自己的对齐数)的整数倍的地址处
- 结构体总大小为最大对齐数(每个成员都有一个对齐数)的整数倍
- 如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,嵌套的结构体大小不变,结构体的整体大小为所有最大对齐数(含嵌套结构体的对齐数)的整数倍
- 例一
struct S1
{
char a;
int b;
char c;
};
- 例二
struct S2
{
int a;
char b;
double c;
};
- 例三
struct S3
{
char a;
double b;
int c;
};
- 例四
struct S4
{
int e;
struct S3;
int f;
char g;
};
特别的,对于数组来说,也满足上述情况,但是对齐数是按照数组的元素类型来说,而且数组的大小是数组的元素总大小。
下面举两个例子来说明情况
例一:
struct S1
{
int a;
char b[5];
short c;
};
例二:
struct S2
{
short d[3];
int e[3];
char f ;
};
关于对齐数的调整: C语言提供了可修改默认对齐数大小的途径:
规则:预处理命令 #pragma pack() ()内为修改后的对齐数大小
当再次使用 #pragma pack() 的时候就恢复了原平台的默认对齐数大小
例:
#pragma pack(2) //修改对齐数为2
struct S1
{
int a;
short c;
};
#pragma pack() //恢复默认对齐数
//此时struct S1的大小为6
总结: 内存对齐是拿系统的空间来换取时间以提升性能的做法,由此,我们在设计结构体时,应尽量让占用空间小的成员集中在一起。