iOS 内存对齐

261 阅读4分钟

内存对齐原则

  1. 数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第⼀个数据成员放在offset为0的地⽅,以后每个数据成员存储的起始位置要从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,⽐如说是数组,结构体等)的整数倍开始(⽐如int为4字节,则要从4的整数倍地址开始存储。 min(当前开始的位置m n) m = 9 n = 4 9 10 11 12
  2. 结构体作为成员:如果⼀个结构⾥有某些结构体成员,则结构体成员要从其内部最⼤元素⼤⼩的整数倍地址开始存储.(struct a⾥存有struct b,b⾥有char,int ,double等元素,那b应该从8的整数倍开始存储.)
  3. 收尾⼯作:结构体的总⼤⼩,也就是sizeof的结果,.必须是其内部最⼤成员的整数倍.不⾜的要补⻬。

示例 1

struct Person2 {
    double a;//8 字节
    int b;// 4字节
    short c;// 2字节
    char d;// 1字节
};
变量a :占8个字节,从0开始,此时 min08),即[0-7] 存储a
变量b :占1个字节,从8开始,此时 min84),8可以整除4,即[8,9,10,11] 存储b
变量c :占2个字节 从12开始,此时 min(12,2), 12可以整除2,即[12,13] 存储c
变量d :占1个字节 从14开始,此时min(14,1), 14可以整除1[14] 存储d
根据内存对其原则三,总大小 15,不是内部成员的最大成员8的整数倍,需要补齐 即大小是 16

示例2

struct Person3 {
    double a;
    int b;
    short c;
    char d;
    Person2 e;
};
变量a :占8个字节,从0开始,此时 min(08),即[0-7] 存储a
变量b :占1个字节,从8开始,此时 min(84),8可以整除4,即[8,9,10,11] 存储b
变量c :占2个字节 从12开始,此时 min(12,2), 12可以整除2,即[12,13] 存储c
变量d :占1个字节 从14开始,此时min(14,1), 14可以整除1[14] 存储d
结构体成员e:e是一个结构体,根据内存对其原则二,结构体成员要从其内部最大元素大小的整数倍地址开始存储,而 e中最大的成员 大小为8,当前是从15开始,不符合要求
        ,需要往后移动到16168的整数倍,符号对其原则,因此[16~31]存储,
        根据内存对其原则三,总大小 32,不是内部成员的最大成员16的整数倍,因此不需要补齐

示例3

struct Person4 {
    char a;//1 字节
    short b;// 2字节
    double c;// 8字节
    int d;// 4字节
};

变量a :占1个字节,从0开始,此时 min01),即[0] 存储a
变量b :占2个字节,从1开始,此时 min12),1不可以整除2,根据规则一,需要往后移动到 22可以整除2,即[2,3] 存储b
变量c :占8个字节 从4开始,此时 min(4,8), 4不可以整除2,根据规则一,需要移动到8,即[8,15] 存储c
变量d :占1个字节 从14开始,此时min(16,1), 16可以整除1[16] 存储d
根据内存对其原则三,总大小 17,不是内部成员的最大成员8的整数倍,需要补齐 即大小是 24`

示例4

struct Person5 {
    double a;
    int b;
    short c;
    char d;
    Person4 e;
};
变量a :占1个字节,从0开始,此时 min(01),即[0] 存储a
变量b :占2个字节,从1开始,此时 min(12),1不可以整除2,根据规则一,需要往后移动到 22可以整除2,即[2,3] 存储b
变量c :占8个字节 从4开始,此时 min(4,8), 4不可以整除2,根据规则一,需要移动到8,即[8,15] 存储c
变量d :占1个字节 从14开始,此时min(16,1), 16可以整除1[16] 存储d
结构体成员e:e是一个结构体,根据内存对其原则二,结构体成员要从其内部最大元素大小的整数倍地址开始存储,而 e中最大的成员 大小为8,当前是从16开始,168的整数倍,符号对其原则,因此[16~39]存储,
        根据内存对其原则三,总大小 40,不是内部成员的最大成员8的整数倍, ,即大小是40

参考

截图.png