这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战
这是一个学会了没啥用,学不会也没关系的知识点
各位大佬实在闲的发慌就听我掰扯掰扯~~~哈哈~~~
话说在遥远的系统深处有个内存分配原则,这个原则是这样的:
- 数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第
⼀个数据成员放在offset为0的地⽅,以后每个数据成员存储的起始位置要
从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,⽐如说是数组,
结构体等)的整数倍开始(⽐如int为4字节,则要从4的整数倍地址开始存
储。
- 结构体作为成员:如果⼀个结构⾥有某些结构体成员,则结构体成员要从
其内部最⼤元素⼤⼩的整数倍地址开始存储.(struct a⾥存有struct b,b
⾥有char,int ,double等元素,那b应该从8的整数倍开始存储.)
- 收尾⼯作:结构体的总⼤⼩,也就是sizeof的结果,.必须是其内部最⼤
成员的整数倍.不⾜的要补⻬。
猛地一看,一坨字,有点蒙
仔细一看。。。。。
还不如猛地一看。。。。
不慌不慌,古人说: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;
}
弄个图片吧:
可以看到两个结构体,内部的元素一样,但是就顺序不一样,最后占用内存大小也不一样,这就是内存分配原则搞的鬼~~~
有没有哪位同学可以对照原则来解释下?
那既然大家都不说话,我就免为其难解释下,哈哈~~~~~~
先看这个结构体:
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
以上是第一条和第三条规则的诠释
下面诠释第二条规则:
如上图,当结构体内部有结构体时,temp 的起始位置要从temp内最大的成员大小的整数倍开始存储,temp内部最大的成员是占8字节,则temp的起始位置是要8的整数倍,所以要从16开始
至此,完美诠释了内存分配原则~~~
正当我在小伙伴面前装逼时,一个可能是想拆我台子的小伙伴上来就来了一句:“兄dei,不是说类也是结构体么?我用类得到的内存大小怎么跟你这原则不匹配?”
拆我台子我能忍?
上来我说了一句话,就把他镇住了, 我说:“我难道不知道类是结构体?我难道不知道类的内存大小不匹配原则?知道我为什么不说吗?难道你不知道这篇字数已经够多了吗?一篇都写完,我怎么参加掘金更文挑战?想知道还不赶紧去找下篇去?还在跟我杠,难道是要我请你吃饭吗?哈哈哈~~~”