iOS 内存对齐

317 阅读3分钟

内存对齐原则

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

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

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

实例解读

1.两个结构体里放相同变量。未嵌套结构体。变量的顺序不同。根据内存对齐原则看内存对齐的结果:

// RTObj1 和  RTObj2 没有嵌套 结构体。 对齐的的时候遵守第一和第三个原则
struct RTObj1 {
    double rt_d;        // 8    (从0开始,占位 0-7)
    char rt_c1;         // 1    (char类型 1字节 1的倍数开始存储, 占位 8)
    int rt_i;           // 4    (int类型 4字节 4的倍数开始存储, 占位 12-15)
    char rt_c2;         // 1    (char类型 1字节 1的倍数开始存储 占位 16)
//    第三个原则收尾  最大为 double 类型 8 字节 所以要以8的倍数为结尾
} rtObj1;               // result = 24


struct RTObj2 {
    double rt_d;        // 8     (从0开始,占位 0-7)
    int rt_i;           // 4     (int类型 4字节 4的倍数开始存储, 占位 8-11)
    char rt_c1;         // 1     (char类型 1字节 1的倍数开始存储 占位 12)
    char rt_c2;         // 1     (char类型 1字节 1的倍数开始存储 占位 13)
    //    第三个原则收尾  最大为 double 类型 8 字节 所以要以8的倍数为结尾
} rtObj2;               // result = 16

输出结果: rtObj1=24 : rtObj2=16

顺便打印了rtObj1里各个变量的地址:输出结果如下:

&rtObj1.rt_d         0x100002100
&rtObj1.rt_c1        0x100002108
&rtObj1.rt_i         0x10000210c
&rtObj1.rt_c2        0x100002110

与注释书写的占位情况符合

2.结构体嵌套结构体,主要为了看内存对齐的第二原则。

struct RTObj3 {
    int rt_i;           // 4    (从0开始,占位 0-3)
    char rt_c1;         // 1    (char类型 1字节 1的倍数开始存储 占位 4)
    double rt_d;        // 8    (double类型 8字节 8的倍数开始存储 占位 8- 15)
    //    第三个原则收尾  最大为 double 类型 8 字节 所以要以8的倍数为结尾
} rtObj3;   // result = 16


struct RTObj4 {
    char rt_c;          // 1    (从0开始,占位 0)
    struct RTObj3 obj;  // 16   (结构体, 16字节, 内部最大元素为 8字节, 根据内存对齐第二原则, 要以8的倍数开始存储, 占位 8 - 23)
    int rt_i;           // 4    (int类型 4字节 4的倍数开始存储, 占位 24-27)
    //    第三个原则收尾  最大为 double 类型 8 字节 所以要以8的倍数为结尾
} rtObj4;   // result = 32

输出结果:rtObj3=16 : rtObj4=32

顺便打印了rtObj4里各个变量的地址:输出结果如下:

&rtObj4.rt_c            0x100002100    
&rtObj4.obj.rt_i        0x100002108
&rtObj4.obj.rt_c1       0x10000210c
&rtObj4.obj.rt_d        0x100002110
&rtObj4.rt_i            0x100002118