002-OC对象原理探究 - 结构体内存对齐

2021-06-16  本文已影响0人  Mr_wick

引言

上一篇文章,探究 alloc的过程中,提到内存对齐。下面我们通过对OC对象QLPerson探究来展开内存对齐的探究。

OC对象本质

我们探究oc对象底层的本质,通过如下方式,讲.m文件转为.cpp文件。参考我的这篇文章
QLPerson.h 代码如下:

image.png
QLPerson.m 如下:
image.png
我通过xcrun来转成cpp文件
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc QLPerson.m -o QLPerson.cpp

QLPerson.cpp拖入xcode,compile sources去掉QLPerson.cpp,使其不参与编译。在QLPerson.cpp中搜索QLPerson_找到底层实现为结构体QLPerson_IMPL

image.png
其中结构体NSObject_IMPL
struct NSObject_IMPL {
    Class isa;
};

由此可得出OC对象的本质是结构体,引出我今天将要探究的结构体内存对齐

结构体内存对齐探究:普通成员变量

定义结构体代码如下:

struct QLStruct1 {
    double  a;  // 8   
    char    b;  // 1   
    int     c;  // 4   
    short   d;  // 2   
} struct1; 
其中每个成员变量后面的注释为类型所占字节大小

那么struct1的内存到底占多少呢?我们这里用sizeof()来计算结果:

NSLog(@"%lu",sizeof(struct1));
打印结果如下: image.png

这24字节是怎么得到的?
首先,我们要了解,结构体对齐有如下原则:

1、数据成员对齐规则:结构(struct)或union的数据成员,第一个数据的成员,放在offset为0 的地方,以后每个数据成员存储的起始位置,要从该成员大小成员的子成员大小(只要该成员有子成员,数组、结构体等)的整数倍开始。
2、结构体作为成员:如果一个结构里,有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。
3、结构体的总大小,也就是sizeOf的结果,必须是其内部成员的整数倍,不足的要补齐
根据内存对齐原则,得到下图是struct1的成员变量的分布情况(excel画的) image.png

代码如下:

struct QLStruct1 {
    double  a;  // 8   0 1 2 3 4 5 6 7
    char    b;  // 1   8
    int     c;  // 4   (9,10,11) 12 13 14 15
    short   d;  // 2   16 17
} struct1;      // 总计:成员变量总和为17,收尾--最大成员变量double(8)的倍数 --> 24
小括号为跳过

9,10,11为什么会空出来,因为struct1的最大成员变量为double,也就是最大成员变量的大小为8字节,根据原则1,可知该结构体按8字节对齐。char b排到8后,int c本应该从9开始排,但是9不能被8整除,因此往后移到12开始分配4字节int c
short d排布结束后,到了17,根据原则3struct1按照8字节内存对齐,不足的需要补齐,因此,最终sizeof(struct1)得到的是24而不是17

结构体内存对齐探究:结构体作为成员变量

struct QLStruct3 {
    double  a;              // 8    0-7
    int     b;              // 4    8 9 10 11
    char    c;              // 1    12
    short   d;              // 2    (13)14 15
    int     e;              // 4    16 17 18 19
    struct  QLStruct1 stru; // 17   (20,21,22,23)24 25 26 27 ... 40
} struct3;                  // 总计:成员变量总和为40,收尾--最大成员变量double(8)的倍数 --> 48
小括号为跳过

根据探究普通成员变量的方式,根据原则2得到sizeof(struct3)的大小为48

总结

结构体内存对齐,要熟记以上3个原则,则面对复杂的结构体,也能得心应手的处理了。

上一篇下一篇

猜你喜欢

热点阅读