一、概念
内存对齐是编译器为每个数据元单位安排在适当的内存位置上。
二、内存对齐原因
为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
三、内存对⻬的原则
数据类型所占字节如下
分析一个案例
struct STStruct1 {
double a; // 8
char b; // 1
int c; // 4
short d; // 2
}struct1;
struct STStruct2 {
double a; //8
int b; //4
char c; //1
short d; //2
}struct2;
上篇文章讲了下对象的本质是结构,我们就研究下结构体。上面两个结构体只不过是类型顺序不一样,那么是不是所占内存大小也一样呢。
编译运行下,结果如下
struct1占24,而struct2竟然占16个这是为什么呢?
struct2
成员变量中最大字节是double,占8个字节,在读取short d时,按内存读取原则,short字节数为2,当前未读地址中,是2的最小倍数就是下标为14了,所以读取14、15。struct2所占字节为16。
struct1
成员变量中最大字节是double,占8个字节,在读取int C时,按内存读取原则,int字节数为4,当前未读地址中,是4的最小倍数就是下标为12了,所以读取12-15,一共是17,是8的倍数呢最小值是24,所以占字节为24。
那么当结构体嵌套结构体会如何呢?
struct STStruct1 {
double a; // 8 (0-7)
char b; // 1 [8 1] (8)
int c; // 4 [9 4] 9 10 11 (12 13 14 15)
short d; // 2 [16 2] (16 17)
}struct1;
struct STStruct2 {
double a; //8 (0-7)
int b; //4 (8 9 10 11)
char c; //1 (12)
short d; //2 13 (14 15)
int e; //16 17 18 19 (20 21 22 23)
struct STStruct1 struct6;
}struct2;
struct6占24位,struct2 不含结构体struct6时也是24,结构体含有结构体时,结构体成员应该从内部最大元素的整数倍开始存储,所以struct6会从下标地址24的开始存储。结果为48.
对齐原则如下
1:数据成员对⻬规则:
结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存储。 min(当前开始的位置mn)m=9n=4 9 10 11 12
2:结构体作为成员:
如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)
3:收尾工作:
结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补⻬。
随手记录下:结构体指针的大小是8,结构体大小是根据成员变量的大小多少来决定。**