这篇文章主要介绍“需要字节对齐的原因有哪些”,在日常操作中,相信很多人在需要字节对齐的原因有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”需要字节对齐的原因有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
字节对齐
现代计算的内存是以字节来划分的,理论上可以计算机可以从任意地址开始访问任意的变量。但实际中,计算机在访问特定类型变量时,经常从特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,这个规则,就叫做内存对齐。
需要字节对齐的原因
计算机是通过总线来访问内存的,而总线的宽度一般是32位或者64位,假设是32位总线,每个总线周期,计算机都会从偶地址开始访问32位内存数据。如果一个32位的数据没有存放在4字节整除的内存地址处,那么处理器就需要2个总线周期才能对其进行访问,自然会降低访问的效率。所以,为了使CPU能够对数据进行快速访问,数据的起始地址应具有“对齐”特性。比如4字节数据的起始地址应位于4字节边界上,即起始地址能够被4整除。
字节对齐的分类
字节对齐分为两种:
结构体对齐,结构体对齐是字节对齐的主要对象。
栈对齐,函数中的局部变量也需要对齐,一般按照4字节对齐。
结构体字节对齐
编译器为结构体的每个成员按照其自然边界分配空间。
各成员按照他们被声明的顺序在内存中顺序的存储。
第一个成员的地址和整个结构体的地址相同。
结构体对齐的4个基本概念
1) 数据类型自身的对齐值:char型数据自身对齐值为1字节,short型数据为2字节,int/float型为4字节,double型为8字节。 2) 结构体或类的自身对齐值:其成员中自身对齐值最大的那个值。 3) 指定对齐值:#pragma pack (value)时的指定对齐值value。 4) 数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中较小者,即有效对齐值=min{自身对齐值,当前指定的pack值}。
期中,有效对其值N,是最终用来决定数据存放地址方式的值。有效对其N表示“对齐在N上”,即该数据的“存放起始地址%N=0”。而数据结构中的数据变量都是按定义的先后顺序存放。第一个数据变量的起始地址就是数据结构的起始地址。结构体的成员变量要对齐存放,结构体本身也要根据自身的有效对齐值圆整(即结构体成员变量占用总长度为结构体有效对齐值的整数倍,以便对结构体数据进行高效的访问)。
结构体对齐的3个基本准则
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 2) 结构体每个成员相对结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding); 3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节{trailing padding}。
第一条:编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该基本数据类型所整除的位置,作为结构体的首地址。将这个最宽的基本数据类型的大小作为上面介绍的对齐模数。
第二条:为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员大小的整数倍,若是,则存放本成员,反之,则在本成员和上一个成员之间填充一定的字节,以达到整数倍的要求,也就是将预开辟空间的首地址后移几个字节。
第三条:结构体总大小是包括填充字节,最后一个成员满足上面两条以外,还必须满足第三条,否则就必须在最后填充几个字节以达到本条要求。
不同处理器间的数据通信
在不同编译平台或处理器上,字节对齐会造成消息结构长度的变化。
编译器为了使字节对齐可能会对消息结构体进行填充,不同编译平台可能填充为不同的形式,大大增加处理器间数据通信的风险。
为了解决上述问题,可以按如下方案进行操作:
1)对于本地使用的数据结构,为提高内存访问效率,采用四字节对齐方式; 同时为了减少内存的开销,合理安排结构体成员的位置,减少四字节对齐导致的成员之间的空隙,降低内存开销。 2)对于处理器之间的数据结构,需要保证消息长度不会因不同编译平台或处理器而导致消息结构体长度发生变化,使用一字节对齐方式对消息结构进行紧缩; 为保证处理器之间的消息数据结构的内存访问效率,采用字节填充的方式自己对消息中成员进行四字节对齐。 3)数据结构的成员位置要兼顾成员之间的关系、数据访问效率和空间利用率。 顺序安排原则是:四字节的放在最前面,两字节的紧接最后一个四字节成员,一字节紧接最后一个两字节成员,填充字节放在最后。
默认的字节对齐方式
32位机一般默认4字节对齐(32位机机器字长4字节),
64位机一般默认8字节对齐(64位机机器字长8字节) 。
更改字节对齐的方式
使用伪指令#pragma pack(n):C编译器将按照n个字节对齐;
使用伪指令#pragma pack(): 取消自定义字节对齐方式。
字节对齐的方式与sizeof的值
不同的字节对齐方式,可能影响sizeof的值,在使用sizeof的时候,要认证考虑当前字节对齐的长度。
在进行网络通信的时候,往往需要传输一块buffer,这个buffer的长度,一定要显示指定,解析的时候也必须使用这个长度。
到此,关于“需要字节对齐的原因有哪些”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。