在alloc的运行流程中我们提到了关于iOS16字节对齐的作用,那么在这篇文章中我们讨论一下,关于内存对齐的一些具体算法。
内存对齐的原则
1.数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说数组,结构体等)的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存储)。
2. 结构体作为成员:如果一个结构体里有某些结构体成员,则结构体成员要从内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里面有char, int ,double等元素,那b应该从8的整数倍开始存储)。
3.结构体总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足要补齐。
上面3条就是内存对齐的原则。如果只看文字的话很难理解,下面我们举例说明,首先我们创建一个结构体,如图所示
在这个结构体中分别有 a b c d 四个参数。那么这四个参数在内存中分别占用了 8个 1个 4个 2个字节。如果不清楚的话 请看帅气的Cooci老师精心准备的图
现在我们知道了每个参数所占的字节数,那么这个参数在内存中是如何分布的呢?
首先根据内存对齐的原则中。第一个数据是从0开始,那么 a 所占的位置就是(0 -7)。
每个数据的起始位置都是该成员的整数倍,那么 b 所占的位置就是 8,但是此时c 所占的字节数是4,9不是4的整数倍。那么就依次往后算到12位4的整数倍,那么c的起始位置就是从12开始占4个字节,就是(12-15), d的起始位置为16 刚好是2的整数倍那么d所在的位置为(16 17),
由于结构体总大小,必须是其内部最大成员的整数倍,不足要补齐的规则。有次可以确定结构体LGStruct所占的内存空间是24。如图所示:
结构体嵌套
如果结构体中嵌套另外一个结构体时,这个时候我们要根据结构体中和子结构体中最大的成员来确定次结构体的最大值。如图所示
在LYHStruct这个结构体中 我们嵌套了 LGStruct1 这个结构体。在这个结构体中。double是次结构体中最大的。那么我们就需要按照8的倍数 去计算整个结构体的大小。如图所示。我们能很轻易的看出来LYHStruct这个结构体的大小为 40.