目录
3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
前言:
结构体内存对齐是非常非常重要的一个知识点经常会在面试题中出现,作为程序员这是一个必须会的知识点,并且能够熟练!
一.offsetof
在学习之前我想先介绍宏:
用来计算结构体成员相对于起始位置的偏移量
头文件是:
#include<stddef.h>
二.结构体对齐规则
1.第一个成员在与结构体变量偏移量为0的地址处。
介绍规则借用下面这段代码解释:
为了更好的解说,我们把下面这种颜色来代替浪费掉的空间:
解说:
表格右边的数字是偏移量
第一个成员变量的位置永远是指向0偏移量的,成员是什么类型就占多大的空间
如上面的c1,他的类型是char占一个字节
2.
从第二个成员变量开始,要对齐到某个数字(对齐数)的整数倍的地址处。 [对齐数] = 编译器默认的一个对齐数 与 该成员大小的较小值。
VS中默认的值为8
Linux默认不设对齐数大小(对齐数就是结构体成员变量本身)
根据上面规则,对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值
这里 i 的对齐数 = 自身大小(4)/ 编译器默认对齐数(8), 取较小值:为4
需要偏移到对齐数的整数倍,这里最近的就是4,中间红色区域就是浪费掉的空间
c2同理
3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
这里大小是计算所占的空间数
这里最大对齐数是4,根据规则必须是4的倍数,到11的位置
因为是从0开始的到11,就是12
我们在来看一个例子:
可以看到S1和S2参数是一样的,只是成员变量的顺序不同。
S1计算大小结果是:12
S2计算大小结果是:8
我们得出结论尽量把小的成员变量放在一起,可以节省空间
小试牛刀:
计算这个结构体大小
(计算出大小后再看结果)
分析:
还有一种情况嵌套了结构体
4.
如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
尝试做一下:
分析:
我们已经知道了s3大小为16 ,按规则s3内部最大的对齐数是8,对应到8的位置占16字节
嵌套情况下的结构体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍
为什么存在内存对齐?
大部分参考质料是这样说的:
1. 平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特 定类型的数据,否则抛出硬件异常。
2.性能原因: 数据结构(尤其是栈)应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
分析:
不对齐与对齐的格式:
内存进行访问时(我们用红色方框来代替访问):
总体来说:
结构体的内存对齐是拿空间来换取时间的做法。
设置默认对齐数:
当你不想对齐或者想用时间换空间的时候就可以这么写1
但一般情况下是写2的n次方数,因为读取的时候不是4个字节就是8个字节
结论:
结构在对齐方式不合适的时候,我们可以自己更改默认对齐数。
制作不易,你们的点赞评论是博主最大动力!!!