一、 结构体回顾
C语言允许用户自己建立由不同类型数据组成的组合型的数据结构,就称为结构体(structre),在其他一些高级语言中称为“记录”(record)。
结构体举例:
struct S1
{
long a;
char b;
int c;
}; // 注意分号不能省略
那么我们如何判断这个结构体所占内存的大小呢??? 在32位机中 结果是 4(long) + 1(char) + 4(int) = 9 ???
9 的结果正确吗??
二、 计算结构体大小
上面举例的结果是12,不是9, 为什么呢?
首先,介绍一下结构的内存对齐的规则:
1. 第一个成员在与结构体变量偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。
3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是
所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
以以下代码为例:
struct S1
{
long a; // 根据规则1. 假设起始地址为1,则该成员的地址为1,占4个字节
char b; // 根据规则2, VS中对齐数8 和 sizeof(b) = 1 中较小的数的整数倍为该成员地址
int c; //根据规则2, VS中对齐数8 和 sizeof(c) = 4 中较小的数的整数倍为该成员地址
};
可通过下图进行理解:
所以其结果是:4+1+3+4=12 // 结果遵循打三个规则,其长度是最大对齐数的整数倍。
练习: 在VS2017中运行
1.
struct S1
{
int a;
char b;
short c;
short d;
};
长度为 12
2.
struct S2
{
int a;
short b;
int c;
char d;
};
长度为 16
3.
struct S3
{
int a;
short b;
int c;
};
struct S4
{
double a;
struct S3 s3; // 计算这个元素时遵循规则4
char d;
};
长度为 24