什么是内存对齐
现代计算机中内存空间都是按照 byte 划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但是实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐。
为什么要内存对齐呢?
- 方便快捷
如果不对齐, 那么就会动态自适应读取内存的长度, 这时候消耗大量性能和时间去计算和适配. - 安全
如果不对齐, 并且没有自适应读取内存, 那么就会出现访问到其他对象的情况,甚至会出现访问到野指针的情况.
对齐后, 系统只需要固定读取长度, 以空间换时间来读取对象的内存, 就会大大提高访问速度以及安全
注意区分x86和64位系统所占空间内存
内存对齐规则
- 数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存储。)
- 结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)
- 结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补⻬。
内存占用规则
结构体内存计算
struct LGStruct1 {
double a; // 大小8 占据位置(0-7)
char b; // 大小1 占据位置(8) 解析 a在b后边 起始位置是8 8是1的整数倍 所以 不需要移位
int c; // 大小4 占据位置(12 13 14 15) b在c后边 起始位置是9 不是4的整数倍 需要位置到12的位置
short d; // 大小2 占据位置(16 17) c在d后边 起始位置是16 是2的整数倍 不需要移位
}struct1;
// 内部需要的大小为: 17
// 最大属性 : 8
// 结构体整数倍: 24
struct LGStruct2 {
double a; //大小8 占据位置(0-7)
int b; //大小4 占据位置(8 9 10 11) 解析 a在b后边 起始位置是8 8是4的整数倍 所以 不需要移位
char c; //大小1 占据位置(12) b在c后边 起始位置是12 不是1的整数倍 不需要移位
short d; //大小2 占据位置(14 15) c在d后边 起始位置是14 是2的整数倍 不需要移位
}struct2;
// 内部需要的大小为: 15
// 最大属性 : 8
// 结构体整数倍: 16