1.对于内存对齐的补充
上一篇博客,我们完成了对结构体内存对齐的基本介绍和几个简单的例子,这篇博客主要是对于上一篇的补充和略微拓展。
怕大家忘记内存对齐的规则,就放在下面了:
1.结构体第一个成员对齐到结构体变量初始位置偏移量为0的地址处(从头开始)
2.其他成员变量要对齐到对齐数的整数倍的地址处(编译器对齐数与变量大小中小的那个的整数倍)
3.结构体总大小为最大对齐数的整数倍(结构体最终大小为最大对齐数的整数倍)
4.如果嵌套了结构体的话,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍
对齐数:编译器默认的一个对齐数和该成员变量大小的较小值
VS中默认对齐数是 8
Linux中gcc没有默认对齐数,对齐数就是成员自身大小
下面有请嵌套了结构体的结构体如何计算内存的典例;
图一 结构体嵌套案例
关于结构体的大小如何计算我们昨天在上一篇博客已经介绍过这里就不多赘叙,我们详细来介绍“小明4”的大小是如何计算的。
图二 结构体嵌套内存条
与其他结构体相同第一个char d对齐到偏移量为0的位置,而第二个是一个结构体,我们首先需要分析这个结构体成员的成员中对齐数最大的是什么,然后在找到偏移量是这个对齐数的整数倍的位置,把这个结构体从这个位置开始储存,在之后我们需要计算这个结构体成员的大小以便于我们可以知道这个结构体所占的空间大小,这样才可以确定下一个变量在内存条中的储存位置,上一篇博客有对于这部分知识的讲解,在这里就不多说了,这个结构体成员的大小是16,将这个结构体成员放进内存条之后,这个时候恰好使用了24个空间,下一个空间的偏移量也是24(要注意是从偏移量0的位置开始存储的),double这个类型的变量大小是8与编译器默认对齐数相同(VS),所以他的对齐数就是8,而24恰好是8的整数倍,所以e直接从偏移量为24的位置开始对齐,最后这个结构体的总大小应该是最大对齐数的整数倍,这个结构体里面的最大对齐数是8,32恰好是8的整数倍,所以这个结构体的总大小就是32。
图三 结构体嵌套案例结果
结果也是和我们刚刚计算的一样,恰好是32。
2.修改对齐数
编译器默认的对齐数其实是可以修改的,这里就要介绍一个新的指令了:
#pragma-----------预处理指令,可改变编译器的默认对齐数:
下面给大家展示一下这个指令是怎么使用的:
图四 修改对齐数
让我们来检验一下对齐数有没有被修改:
图五 检验对齐数是否被修改
今天唠这么多,明天唠唠结构体传参都怎么个事儿