ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

关于结构体对齐

2022-02-06 16:59:59  阅读:114  来源: 互联网

标签:变量 数据类型 内存 类型 对齐 结构 关于


首先我们先了解一下各数据类型所占的字节数

x64系统(64位)

 x86系统(32位)

 

在这里有一个很有意思的点,我使用VS在x86与x64系统下运行出来的long类型所占据的空间都是4个字节,这与我们之前在书上所学的不同,按照部分(我也不敢确定所有)的C语言书上所说,在64位操作系统下,long类型的大小应该是8个字节的,但这明显与上方结果不同。为此,我特意又到了64位的Linux虚拟机上检测了一下,所得结果如下:

 

 之后又查询了更加专业的资料,可知long类型属于那一种没有将标准统一的类型,属于C/C++各数据类型中的一个异类。对于它我们不必过多的纠结,在实践中最好也不要使用这个异类,它会导致我们程序的可移植性大大降低。

当我们需要更大范围的整型时,最好直接使用long long来定义变量。


 下面开始正文,结构体对齐。

首先我们要知道什么是结构体,官方点的语言来描述,结构体是C/C++语言中一种用户自定义的可用的数据类型,它允许用户存储不同类型的数据项。

当我们定义一个结构体类型,并且定义出一个该类型的变量时,系统会根据其默认的规则在内存中为结构体申请相应大小的空间——就如我们所理解的基本数据类型变量的定义一般。

而C/C++作为接近底层且高效的语言,结构体究竟依照什么样的规则在内存中申请空间便是我们所必须要了解的一个知识点了。

这里我们要提到一个东西:

内存对齐

 用简单点的话来说就是——把东西按照规则放在合适的地方。

关于为什么要有内存对齐,很多参考资料上如是说:

1.平台原因:不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。(移植原因)

2.性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

这涉及到了一些深层次的知识点,所以我也只能这样照搬过来,具体理解后,可能会在后续的博客中解释 。


对齐规则

1. 第一个成员在与结构体偏移量为 0 的地址处。 2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS 中默认的对齐数为 8 3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。 4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

这应该属于比较官方的释义——大部分的博客中是这样写的。

但对于很多人来说这样的确会给不少人带来阅读理解上的麻烦,并且在实例的判断上也有些麻烦。

因此,我们可以通过如下方式来计算结构体的大小:

struct stu {
    char name;
    double a;
    int id;
    char grade;
};

第一步:确定结构体的最大对齐数——即结构体中 最大数据类型的大小 与 默认对齐数 二者之中的较小值。

如上方例子中,最大数据类型即double,占8个字节,而VS中的默认对齐数为8,二者相等,较小值也为8。这里并不能体现出,后续会有修改。

第二步,将从起始位置开始的内存看作一个个大小为最大对齐数的小单位,将结构体中的结构变量依次放入这些单位中。

如果该单位剩余空间可以放下下一个结构变量,则将下一个结构变量紧接着前一个结构变量放入。

相反,如果该单位的剩余空间不足以放下下一个结构变量,则将下一个结构变量放到下一单位起始处(如果该结构变量足够大,它可能会占数个单位)。

重复此过程。

对于结构体中所包含的结构体,在计算最大对齐数时,往往不将被包含的结构体看作一个成员变量,而是将其包含的成员变量单独拿出来比较计算的。

可以认为最大对齐数是通过 结构体包含或间接包含的基本数据类型/指针类型的所占空间最大值 与 系统默认对齐数 二者的较小值。

 

 

可见数组类型在内存对齐的规则中是不会将它看作一个整体的。此图中结构体struct stu中的元素所占空间最大的是char[16],占了16个字节,而系统所根据的最大对齐数确实8个字节。char[16]在此处只是被看作了16个char变量。 

 

不得不说当你理解了一个方法之后,如何将它简单而又清楚的讲出来也是一件很有挑战的事,显然我是没有这样的天赋的。

标签:变量,数据类型,内存,类型,对齐,结构,关于
来源: https://blog.csdn.net/qq_56713382/article/details/122796603

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有