1.编译器默认的内存对齐规则
默认的对齐规则是一个变量的地址需要是其类型的长度的整数倍:
例如下面这个结构体:
struct A
{
char m1;
short m2;
int m3;
}
对于A变量的m1成员,其大小为1个字节,起始地址为0,可以满足整除的要求
对于A变量的m2成员,其大小为2个字节,因此起始地址1不满足被2整除,需要按照2字节对齐,因此,其起始地址为2,占用2,3两个字节
对于A变量的m3成员,其大小为4个字节,因此其起始地址4满足整除4这个要求
最终该结构的内存结构如下:
m1 | 对齐 | m2 | m2 |
m3 | m3 | m3 | m3 |
2.指定对齐方式
目前可以通过pragma pack命令或者std::align手动设置对齐方式
有效对其值:是给定值#pragma pack(n)和结构体中最长数据类型长度中较小的那个。有效对齐值也叫对齐单位。
上面这一句是知乎上找到的,换成自己的理解就是:
当变量的类型长度小于我们自己设置的对齐系数,那么变量的数据类型长度来对齐,反之,按照按照我们设置的对齐系数来对齐
例如:
struct struct_Test2
{
char c;
int i;
char c1;
double d;
};
那么不主动设置对齐系数,其内存布局应该如下:
一字节 | 一字节 | 一字节 | 一字节 |
---|---|---|---|
c | 对齐 | 对齐 | 对齐 |
i | i | i | i |
c1 | 对齐 | 对齐 | 对齐 |
对齐 | 对齐 | 对齐 | 对齐 |
d | d | d | d |
d | d | d | d |
设置了4字节对齐系数后,其内存布局中d的起始地址按照4字节对齐,而不是其类型长度8字节,可以让c1后面只补3个字节的对齐位
c1 | 对齐 | 对齐 | 对齐 |
d | d | d | d |
d | d | d | d |
以上