iOS 结构体内存对齐

前言

我们都知道,程序中的每一个变量,常量,类,结构体等等都会由系统分配自己的内存空间,针对于不同的代码,系统分配内存的规则也不尽相同,那么今天我们就一块儿看一下在iOS中系统针对于结构体是如何处理的;

在了解结构体内存分配之前,我们先通过一张图片了解一下,我们常用数据类型在在内存中所占用的内存大小:
复制代码

image.gif
首先我们先通过文字来来了解一下结构体内存分配的规则:

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的结果,.必须是其内部最⼤成员的整数倍.不⾜的要补⻬

所谓只通过文字解释而不通过代码验证的博客就是耍流氓;接下来我们就通过代码一块儿来看一下结构体的内存分配到底是什么样子的;

image.gif

根据上图我们看一看到,我们创建了两个结构体CYFStruct1和CYFStruct2,他们分别有a,b,c,d四个变量;如果我们仔细观察,除了变量b和c在结构体中的顺序不同意外其他是完全相同的,那么struct1和struct2在内存中所占的大小是否一样呢?我们根据上边所说的原则一块儿来计算一下;

首先由CYFStruct1,我们可以看到a,b,c,d这四个变量占字节数最多的是double类型,所占字节数为8,所以,以double类型开始,我们给a分配8个字节[0-7];

接下来是b为char类型,char类型所占字节数为1,我们按照“以后每个数据成员存储的起始位置要从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,⽐如说是数组,结构体等)的整数倍开始”这个原则,8为1的整数倍,所以我们给b分配一个字节[8];

然后到了c,c为int类型,int类型所占字节数为4,根据整数倍原则,接下来的9,10,11都不是4的整数倍,所以我们应该从12开始,所以c的内存为(9,10,11,[12,13,14,15];

最后我们看d为short类型,short类型所占字节数为2,根据整数倍原则,接下来的16为2的整数倍,所以d的内存为[16,17]

最终我们在根据“结构体的总⼤⼩,也就是sizeof的结果,.必须是其内部最⼤成员的整数倍.不⾜的要不齐”原则,在CYFStruct1中的最大成员为double类型,所占字节数为8,所以从17往后8的最小整数倍为24;

所以我们可以得出结论CYFStruct1所占内存为24;

由于结构体CYFStruct1和CYFStruct2,所有的成员变量都是相同的那么他们所占内也是相同的吗?我们来验证一下

首先CYFStruct2,最大成员变量为a,为double类型,所以我们可以给他分配8个字节[0-7];

接下来是b为int类型,我们可以给他分配4个字节[8-11];

然后到了c为char类型,我们可以给他分1个字节[12];

最后到了d为short类型, 根据其实位置是整数倍原则我们不能将13分给d,所以我们需要从14开始于是就成了这样(13,[14-15]

最终我们在根据“结构体的总⼤⼩,也就是sizeof的结果,.必须是其内部最⼤成员的整数倍.不⾜的要不齐”原则,在CYFStruct2中的最大成员为double类型,所占字节数为8,所以接下来的16满足条件
于是乎,CYFStruct2的内存为16个字节;

是不是很吃惊,是不是很诧异,接下来我们功过运行代码来看一下!

image.gif

由上图可以看出来,系统给这两个结构体分配的内存确实是24和16;

到这里为止,我们已经了解了简单的结构体内存的分配方式,那么如果一个结构里里边还有的属性是一个结构体的话,我们应该怎么计算呢?如下图:

image.gif

从图片中我们可以看出到,CYFStruct3里边有一个参数str,str为结构体类型,此时struct3的应该分配多少内存呢?我们一块儿来探索一下:

首先我们可以直观的看出来CYFStruct3里边最大属性为a为double类型,占8个字节,所以a的应该分配0-7,8个字节;

然后b为int类型,占4个字节,根据起始位置为整数被原则b的内存分配应该为[8-11]

然后c为char类型,占一个字节,所以它的内存为12;

然后d为short类型,占2个自己,接下里来的13不满足条件,所以应该从14开始,所以d的内存为(13,[14-15];

然后e为int类型,占4个字节,起始值为16,满足整数倍的条件,所以e的内存为[16-17] ;

最后我们看str,str为结构体类型,同样我们要计算它的内存分配的时候也要遵循上边所说的三大原则;

我们先找出最大属性a为double类型,占8个字节,起始为止18,不是8的整数倍,大于18又是8的整数倍的是24,所以a的内存为[24-31];

同样的步骤我们计算到str中d的时候内存为[40-41]

这时候我们根据规则中的第三条“结构体的总⼤⼩,也就是sizeof的结果,.必须是其内部最⼤成员的整数倍.不⾜的要补齐”可以得出,48为大于41切为8的倍数的最小值,所以CYFStruct3的所占内存为48;

image.png
我们再次通过代码来验证:

image.gif

通过控制台打印结果来看,我们的计算是正确的

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享