一、内存对齐
1、什么是结构体内存对齐:
结构体内可以包含不同类型的数据,每个结构体的大小也不是单纯把各个数据字节数相加。每个成员在内存中按一定的偏移量来存储,每个成员都要以一定的对齐数进行对齐存储,整个结构体也要按照一定的对齐数进行对齐
VS默认对齐数 8
Linux默认对齐数 4
2、对齐原因:
①平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
②性能原因:CPU以cache line为单位读写内存,为了不让结构体内的成员变量分布在多个cache line上,而对齐的内存访问仅需要一次访问。
3、对齐规则:
①第一个成员变量的字节要是第二个成员字节的倍数(向下看齐),第一二个成员变量的字节要是第三行变量字节数的倍数,以此类推,不够就+
结构体中的所有成员其首地址偏移量必须为器数据类型长度的整数被,其中第一个成员的首地址偏移量为0
struct B
{
char a;//1+1 偏移量0
short b;//2 第一行+1后才是2的倍数 偏移量2
int c;//4 前两行加起来是4 是本行的倍数所以不用+ 偏移量4
}//该结构体大小8个字节
②整个结构体的大小应该能是该结构体中单个最大成员大小的倍数。
struct D
{
char num;//1+3
struct{
char sex;//1
int num//4
}ss;//4
float scores;//4
}//12
struct E
{
int a;//4
char b;//1
};//5+3
struct H
{
char a;//1+3
struct HH
{
int b;
long c;
}d;//8 注意这里定义变量了
};//12 也就是说第一行 看第二行结构体的单个成员大小 而第二个自己是8
struct K
{
char a;//1+1
short b[4];//8
int c;//4
};//14+2
struct I
{
char a;//1
struct II
{
int b;
long c;
};//没有定义变量
};
struct J
{
char a;
struct
{
int b;
long c;
};//定义了一个没有名字的变量
};
③人为指定:
#pragma pack()//以指定数对齐
#pragma pack(4)
struct C
{
char a;//1+3 //按4对齐 不是4的倍数 就+3
double d;//8
};//12
#pragma pack()