iOS 内存分配原则介绍1/2

384 阅读4分钟

这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

这是一个学会了没啥用,学不会也没关系的知识点

image.png

各位大佬实在闲的发慌就听我掰扯掰扯~~~哈哈~~~

话说在遥远的系统深处有个内存分配原则,这个原则是这样的:

  1. 数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第

⼀个数据成员放在offset为0的地⽅,以后每个数据成员存储的起始位置要

从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,⽐如说是数组,

结构体等)的整数倍开始(⽐如int为4字节,则要从4的整数倍地址开始存

储。

  1. 结构体作为成员:如果⼀个结构⾥有某些结构体成员,则结构体成员要从

其内部最⼤元素⼤⼩的整数倍地址开始存储.(struct a⾥存有struct b,b

⾥有char,int ,double等元素,那b应该从8的整数倍开始存储.)

  1. 收尾⼯作:结构体的总⼤⼩,也就是sizeof的结果,.必须是其内部最⼤

成员的整数倍.不⾜的要补⻬。


猛地一看,一坨字,有点蒙

仔细一看。。。。。

还不如猛地一看。。。。

image.png

不慌不慌,古人说:show your code .....

咱先弄个例子看看

#import <malloc/malloc.h>
#import <objc/runtime.h>

struct TTStruct1 {
    char a;     //1字节 -- 占据0字节
    double b;   //8字节 -- 占据8-15字节
    int c;      //4字节 -- 占据16-19字节
    short d;    //2字节 -- 占据20-22字节
} MyStruct1;    //共22字节,但22不是8的倍数,则+2,因为24是8的倍数

struct TTStruct2 {
    double b;   //8字节 -- 占据0-7字节
    int c;      //4字节 -- 占据8-11字节
    char a;     //1字节 -- 占据12字节
    short d;    //2字节 -- 占据14-15字节
} MyStruct2;    //共16字节,16是8的倍数所以总大小还是16字节

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSLog(@"TTStruct1 size:%lu",sizeof(MyStruct1));
        NSLog(@"TTStruct2 size:%lu",sizeof(MyStruct2));
    }
    return 0;
}

弄个图片吧:

image.png

可以看到两个结构体,内部的元素一样,但是就顺序不一样,最后占用内存大小也不一样,这就是内存分配原则搞的鬼~~~

image.png

有没有哪位同学可以对照原则来解释下?

那既然大家都不说话,我就免为其难解释下,哈哈~~~~~~

image.png

先看这个结构体:

struct TTStruct1 {
    char a;     //1字节 -- 占据0字节
    double b;   //8字节 -- 占据8-15字节
    int c;      //4字节 -- 占据16-19字节
    short d;    //2字节 -- 占据20-22字节
} MyStruct1;    //共22字节,但22不是8的倍数,则+2,因为24是8的倍数

第一个成员是char类型,char类型占1个字节,所以占据第0个字节

第二个成员是double类型,double类型占8个字节,根据原则1起始位置是要当前类型大小的整数倍开始,所以要从8的整数倍开始,所以虽然第一成员只占据了第0字节,第二个成员还是要依据规则从第8个字节开始存储,所以第二个成员占据8-15字节

第三个成员是int类型,int类型占4个字节,所以要从4的整数倍开始存储,因为第二个成员占据了8-15字节,下个字节就是第16个字节所以直接从16字节开始存储,所以第三个成员占据了16-19字节

依次类推,第四个占据20-22字节,至此这个结构体大小时22字节,但原则3规定,总大小必须是内部最大成员的整数倍,内部最大成员是占8字节,则结构体大小一定要是8的整数倍,所以总大小+2,24就是8的整数倍了。

最终这个结构体大小是24

以上是第一条和第三条规则的诠释

下面诠释第二条规则:

image-20211103224952946

如上图,当结构体内部有结构体时,temp 的起始位置要从temp内最大的成员大小的整数倍开始存储,temp内部最大的成员是占8字节,则temp的起始位置是要8的整数倍,所以要从16开始

至此,完美诠释了内存分配原则~~~

image.png

正当我在小伙伴面前装逼时,一个可能是想拆我台子的小伙伴上来就来了一句:“兄dei,不是说类也是结构体么?我用类得到的内存大小怎么跟你这原则不匹配?”

image.png

拆我台子我能忍?

上来我说了一句话,就把他镇住了, 我说:“我难道不知道类是结构体?我难道不知道类的内存大小不匹配原则?知道我为什么不说吗?难道你不知道这篇字数已经够多了吗?一篇都写完,我怎么参加掘金更文挑战?想知道还不赶紧去找下篇去?还在跟我杠,难道是要我请你吃饭吗?哈哈哈~~~”