在C/C++中使用sizeof()计算结构体所占内存时获得的字节数并不是每个成员变量的所占字节大小的和,如定义结构体A
struct A
{
int a1;
char a2;
};
sizeof(A)返回的值为8,而不是sizeof(int)+sizeof(char)=5
另外结构体成员变量的顺序不同,结构体所占的内存大小可能也不一样,定义结构体B
struct B
{
char b1;
int b2;
char b3;
};
sizeof(B)返回的值为12,但是如果将b1和b2定义的顺序交换,则会得到不同的值
struct C
{
int b2;
char b1;
char b3;
};
sizeof(C)返回的值为8,这些都是因为字节对齐机制导致的。
处理器读取对齐的数据比读取不对齐的数据速度要快,因此编译器会将这些数据在内存中对齐,字节数小于对齐字节数的变量后面会填充多出的字节。
对齐字节数以结构体成员变量中字节数最大的为准,在结构体A,B,C中都是以int所占字节数4为对齐字节数,他们在内存中的分布如下:
结构体A的内存分布
结构体B的内存分布
结构体C的内存分布
结构体成员变量按定义的顺序分布在内存中,如果两个或两个以上相邻成员变量的字节数都小于对齐字节数并且字节数之和也小于对齐字节数,则这两个变量分布在同一对齐数据块内,如结构体C中的b1和b3字节数之和为2,小于sizeof(int)=4,所以b1和b3分布在同一数据块的相邻字节,sizeof(C)=8。而结构体B中的b1和b3不相邻,所以b1和b3单独占据4字节的内存块,sizeof(B)=12。
合理安排成员变量类型和顺序可以减少结构体所占内存字节数,例如把占字节数大的放在前面,占字节数小的放在后面。
注:如果不想使用字节对齐或者想自定义字节对齐方式可使用#pragma pack (n),指定对齐字节数为n,当n=1的时候成员变量紧凑排列在内存中,也就是没有使用字节对齐,如果未指定n值则恢复默认对齐方式。