内存对齐机制(Memory Alignment):提高CPU访问内存数据的效率。
先看数组,由于数组的类型都一样,所以数组的大小=类型大小*成员个数。无缝隙存储。
但是结构体里面放的类型很多时候都不一样,那么就会有问题。
环境:假设是32位系统,则默认按4字节对齐。即4个一组,比如int型变量,则必须从0,4,8,12…这样的位置起头放(刚好被4整除)。如果是short,则是0,2,4,8…(刚好被2整除)。char就无所谓了,哪里都可以(都可以被1整除)。
32系统:计算机硬件+操作系统+编译器都是32位。
结论1:分配的首地址可以被该变量大小整除。如果默认是4字节对齐,那double这样超过4字节的,还是按4字节算。
//8=1+1+ 空两格 +4
struct Demo1
{
char a;
char b;
int c;
};
//看起来是1+1+4 = 6;
但是如果是:
struct Demo2
{
int c; //换了位置
char a;
char b;
};
//看起来6,4是先放好了,再放两个1。但是还是8。
结论2:总大小必须为结构体中类型宽度最大的数据成员的宽度的整数倍。一样,如果默认是4字节对齐,那double这样超过4字节的,还是按4字节算。
也就是算出来是6,但是你最大的int是4,那么就要补成8。也就是后面空着的两位也算你的。
//12 = 1 + 空3个 + 4 + 1 + 空3个
struct Demo3
{
char a;
int i;
char c;
};
//很浪费,所以尽量把类型一样的放在一起。
如果结构体A包含结构体B的东西:
struct Demo1
{
char a;
char b;
int c;
};//8
struct Demo5
{
char c;
struct Demo1 s;
};//4+8 = 12
此时结构体1的类型大于4,按4算(还是因为默认4字节对齐),然后char c就按4对齐。
如果:
struct Demo1
{
char a;
};//1
struct Demo5
{
char c;
struct Demo1 s;
};//1+1 =2
此时char c就按1对齐。
结论3:结构体A中有结构体B的成员,A的成员按结构体B中类型宽度最大的数据成员对齐。对齐规则参考结论1、2
以上都是按4字节对齐,4称为对齐模数,可以改:
#pragma pack(n) //按n字节对齐
#pragma pack () //解除对齐
如果按1字节对齐,那么就直接无脑加就好了。
其他的情况就依次按着结论把4依次改成n就好了。