结构体内存对齐规则
- 第一个成员:结构体的第一个成员总是从结构体变量内存起始位置开始存储。
- 其他成员:其他成员存储的起始位置要对齐到某个特定值(对齐数)的整数倍的地址处。对齐数是该成员自身大小与编译器默认对齐数中较小的那个值。例如,在32位系统中,编译器默认对齐数一般为4字节,若成员是
char
(1字节),则对齐数为1;若成员是int
(4字节),对齐数为4。
- 结构体大小:结构体的总大小为最大对齐数(所有成员对齐数中的最大值)的整数倍。如果不够,需要在最后一个成员后面填充字节,以满足这个条件。
示例代码及分析
#include <stdio.h>
// 定义包含不同数据类型成员的结构体
struct MyStruct {
char a; // 1字节
int b; // 4字节
short c; // 2字节
};
int main() {
printf("结构体MyStruct的大小: %zu 字节\n", sizeof(struct MyStruct));
return 0;
}
原因分析
- 成员
a
:a
是char
类型,大小为1字节,它从结构体起始位置开始存储。
- 成员
b
:b
是int
类型,大小为4字节。由于默认对齐数假设为4(32位系统常见情况),所以b
存储的起始位置必须是4的整数倍。此时,a
后面还剩3个字节空间不足4字节,所以需要填充3个字节,b
从第4个字节位置开始存储。
- 成员
c
:c
是short
类型,大小为2字节,对齐数为2(short
自身大小2与默认对齐数4中较小值)。b
占用4字节后,下一个地址是第8个字节,满足c
对齐到2的整数倍的要求,c
从第8个字节位置开始存储,占用2个字节。
- 结构体总大小:最大对齐数是4(
int
的对齐数),此时结构体已经占用了1 + 3(填充)+ 4 + 2 = 10字节,不是4的整数倍,所以需要在c
后面填充2个字节,使得结构体总大小为12字节,满足最大对齐数的整数倍。所以sizeof(struct MyStruct)
结果为12字节。