数据对齐Word下载.docx
《数据对齐Word下载.docx》由会员分享,可在线阅读,更多相关《数据对齐Word下载.docx(14页珍藏版)》请在冰豆网上搜索。
译命令#pragmapack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。
规则1:
数据成员对齐规则:
结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset
为0的地方,以后每个数据成员的对齐按照#pragmapack指定的数值和这个数据成员自身长度中,比较小的那个进行。
规则2:
结构(或联合)的整体对齐规则:
在数据成员完成各自对齐之后,结构(或联合)本身也要进
行对齐,对齐将按照#pragmapack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。
规则3:
结合1、2颗推断:
当#pragmapack的n值等于或超过所有数据成员长度的时候,这个n
值的大小将不产生任何效果。
三、试验
我们通过一系列例子的详细说明来证明这个规则吧!
我试验用的编译器包括GCC3.4.2和VC6.0的C编译器,平台为WindowsXP+Sp2。
我们将用典型的struct对齐来说明。
首先我们定义一个struct:
#pragmapack(n)/*n=1,2,4,8,16*/
structtest_t
{
inta;
charb;
shortc;
chard;
};
#pragmapack(n)
首先我们首先确认在试验平台上的各个类型的size,经验证两个编译器的输出均为:
sizeof(char)=1
sizeof(short)=2
sizeof(int)=4
我们的试验过程如下:
通过#pragmapack(n)改变“对齐系数”,然后察看sizeof(structtest_t)的值。
1、1字节对齐(#pragmapack
(1))
输出结果:
sizeof(structtest_t)=8[两个编译器输出一致]
分析过程:
1)成员数据对齐
#pragmapack
(1)
structtest_t{
/*长度4<
1按1对齐;
起始offset=00%1=0;
存放位置区间[0,3]*/
/*长度1=1按1对齐;
起始offset=44%1=0;
存放位置区间[4]*/
/*长度2>
起始offset=55%1=0;
存放位置区间[5,6]*/
起始offset=77%1=0;
存放位置区间[7]*/
#pragmapack()
成员总大小=8
2)整体对齐
整体对齐系数=min((max(int,short,char),1)=1
整体大小(size)=$(成员总大小)按$(整体对齐系数)圆整=8/*8%1=0*/[注1]
2、2字节对齐(#pragmapack
(2))
sizeof(structtest_t)=10[两个编译器输出一致]
#pragmapack
(2)
/*长度4>
2按2对齐;
起始offset=00%2=0;
/*长度1<
2按1对齐;
/*长度2=2按2对齐;
起始offset=66%2=0;
存放位置区间[6,7]*/
起始offset=88%1=0;
存放位置区间[8]*/
成员总大小=9
整体对齐系数=min((max(int,short,char),2)=2
整体大小(size)=$(成员总大小)按$(整体对齐系数)圆整=10/*10%2=0*/
3、4字节对齐(#pragmapack(4))
sizeof(structtest_t)=12[两个编译器输出一致]
#pragmapack(4)
/*长度4=4按4对齐;
起始offset=00%4=0;
4按1对齐;
/*长度2<
4按2对齐;
整体对齐系数=min((max(int,short,char),4)=4
整体大小(size)=$(成员总大小)按$(整体对齐系数)圆整=12/*12%4=0*/
4、8字节对齐(#pragmapack(8))
#pragmapack(8)
8按4对齐;
8按1对齐;
8按2对齐;
整体对齐系数=min((max(int,short,char),8)=4
5、16字节对齐(#pragmapack(16))
#pragmapack(16)
16按4对齐;
16按1对齐;
16按2对齐;
整体对齐系数=min((max(int,short,char),16)=4
四、结论
8字节和16字节对齐试验证明了“规则”的第3点:
“当#pragmapack的n值等于或超过所有数据成员长度的时候,这个n值的大小将不产生任何效果”。
另外内存对齐是个很复杂的东西,上面所说的在有些时候也可能不正确。
呵呵^_^
[注1]
什么是“圆整”?
举例说明:
如上面的8字节对齐中的“整体对齐”,整体大小=9按4圆整=12
圆整的过程:
从9开始每次加一,看是否能被4整除,这里9,10,11均不能被4整除,到12时可以,则圆整结束。
程序校验(环境VC++6.0)
intmain()
//ox0012ff1cox0012ff18ox0012ff14ox0012ff10
printf("
ox%08x"
&
a);
b);
c);
ox%08x\n"
d);
}
此页面可以通过在dev_c++4.9.9.2运行,并通过小量的更改在其他IDE下运行.
摘要:
本文描述了内存对齐的各种概念和内存管理的其他知识点,应用相应的程序示例进行解释.
备注:
本文资料收集于网络并通过作者整理.此篇不考虑继承和虚函数虚表问题.此类问题分析详见下个版本.
whatandwhy
什么是字节对齐,为什么要对齐?
现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐.
对齐的作用和原因?
各个硬件平台对存储空间的处理上有很大的不同.一些平台对某些特定类型的数据只能从某些特定地址开始存取.比如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对齐数据存放进行对齐,会在存取效率上带来损失.比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据.显然在读取效率上下降很多.
4个重要概念
1.数据类型自身的对齐值:
对于char型数据,其自身对齐值为1;
对于short型为2;
对于int,float,double类型,
其自身对齐值为4单位字节.
2.结构体或者类的自身对齐值:
其成员中自身对齐值最大的那个值.
3.指定对齐值:
#pragmapack(value)时的指定对齐值value.
4.数据成员,结构体和类的有效对齐值:
自身对齐值和指定对齐值中小的那个值.
有效对齐值拓展
有效对齐值n是最终用来决定数据存放地址方式的值.有效对齐n,就是表示对齐在n上,也就是说该数据的"
存放起始地址%n=0"
.而数据结构中的数据变量都是按定义的先后顺序来排放的.第一个数据变量的起始地址就是数据结构的起始地址.结构体的成员变量要对齐排放,结构体本身也要根据自身的有效对齐值圆整(就是结构体成员变量占用总长度需要是对结构体有效对齐值的整数倍,结合下面例子理解)