内存对齐原则

1,500 阅读3分钟

1.数据成员对齐规则: 结构(struct)(或联合(union))的数据成员,第一个数据成员放在 offset 为 0 的地方,以后没个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如 int 为 4 字节,则要从 4 的整数倍地址开始存储).

2.结构体作为成员: 如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素的大小的整数倍地址开始存储.(struct a 里存有 struct b,b 里有 char,int,double 等元素,那 b 应该从 8 的整数倍开始存储.)

3.收尾工作: 结构体的总大小,也就是 sizeof 的结果,必须是其内部最大成员的整数倍,不足的要补齐

例子:

struct Struct1 {

char a;             // 1 + 7  [0-7]

double b;        // 8   min[8 8] , [8,9,10,11,12,13,14,15]

int c;                // 4   min[16 4] , [16,17,18,19]

short d;           // 2   min[20 2] , [20,21]

} MyStruct1;

假如内存是 0 开始存储,

char a 为 1 字节,因为 double b为 8 字节,所以,char a 存储区间位 [0-7],

double b 位 8 字节,存储区间为[8-15],

int c 为4 字节,存储区间为 [16-19],

short d 为 2 字节,存储区间为 [20-21],

成员对齐后,结构体要对齐字节,21 不是8 的倍数,所以sizeof(MyStruct1)取值 24.

例子 2

struct Struct2 {

double b;         // 8  0 + 7  [0-7]

char a;             // 1    min[8 1]  [9]  

int c;                // 4    min[9 4] 因为 9 不是 4 的整数倍所以存储区间[9,10,11]用来填充,从                                              [12,13,14,15]

short d;           // 2    min[16 2] [16,17]

} MyStruct2;

17 不是 8 的整数倍,所以sizeof(MyStruct2)取值 24.

例子 3

struct Struct3 {

double b;         // 8  0+7  [0-7]

int c;                // 4  min[8 4]  [8,9,10,11]

char a;             // 1  min[12 1]  [12]  

short d;           // 2 min[13 2]   所以[13] 用来填充,用[14,15] 

} MyStruct3;

15 不是 8 的整数倍,最小整数倍为 16,所以sizeof(MyStruct3)取值 16.

为了方便内存读取的效率,内存读取单位不是以字节为单位,而是通过一块一块来读取,通过空间换取时间,提高性能.

PS: 对象里面的属性是以 8 字节对齐,保证属性与属性之间的容错,保证属性之间更加安全.

       对象是以 16 字节对齐,保证对象与对象之间的容错,保证对象之间更加安全.