c语言中结构体的对齐

上传人:小** 文档编号:99179680 上传时间:2022-05-31 格式:DOC 页数:6 大小:98KB
收藏 版权申诉 举报 下载
c语言中结构体的对齐_第1页
第1页 / 共6页
c语言中结构体的对齐_第2页
第2页 / 共6页
c语言中结构体的对齐_第3页
第3页 / 共6页
资源描述:

《c语言中结构体的对齐》由会员分享,可在线阅读,更多相关《c语言中结构体的对齐(6页珍藏版)》请在装配图网上搜索。

1、语言中结构体的对齐转自:1叮-结构体数据成员对齐的意义许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的起始地址的值是某个数的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment叮oduiu。这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度。比如这么一种处理器,它每次读写内存的时候都从某个8倍数的地址开始,一次读出或写入8个字节的数据,假如软件能保证doubi类型的数据都从8倍数地址开始,那么读或写一个dOUblQ类型数据就只需要一次内存操作。否则,我们就可能需要两次内存操作才能完成这个动作,因为数

2、据或许恰好横跨在两个符合对齐要求的字节内存块上。2叮-结构体对齐包括两个方面的含义1)结构体总长度P2)结构体内各数据成员的内存对齐,即该数据成员相对结构体的起始位置3叮结构体大小的计算方法和步骤(20120902)1)将结构体内所有数据成员的长度值相加,记为sum_a,此值仅对最后计算sum叮并对结构体整体对齐有意义;a2)将各数据成员(数组拆开看)为了内存对齐,该数据相对起始位置应该是对齐模数的整数倍对齐模数是#pragmaapack旨定的数值以及该数据成员自身长度中数值较小者。按各自对齐模数而填充的字节数累加到和um_a上,记为sum_b。3)将和sum_b向结构体模数对齐,该模数是cp

3、ragmaapac指定的数值和结构体内部最大的基本数据类型成员长度中数值较小者。结构体的长度应该是该模数的整数倍。4Q-结构体大小计算举例在计算之前,我们首先需要明确的是各个数据成员的对齐模数,对齐模数和数据成员本身的长度以及ragmaapac编译参数有关,其值是二者中最小数。如果程序没有明确指出,就需要知道编译器默认的对齐模数值。下表是indOWSaXP/DEV-C+和32位QLinuX/GC中基本数据类型的长度和默认对齐模数。其他平台各类型a变量的默认对齐模数可以通过_aiignof_(varanaa查看。DcharshortintiongdoubielongadoubieWindows长

4、度124488模数124488Linux长度1244812模数124444D例子1:structamy_structaaaaaacharaa;aaaaaiongadoubieab;a;此例子Windows和Linu计算方法有些许不一致。a在Windows中计算步骤如下:a步骤1:所有数据成员自身长度和:1Ba+a8Ba=a9Ba-asum_aa=a9Ba步骤2:数据成员a放在相对偏移0处,之前不需要填充字节;数据成员d为了内存对齐,根据“结构体大小的计算方法和步骤”中第二条原则,其对齐模数是8之前需填充7个字节,sum_aa+a7a=a16Ba-asum_ba=a16aBa步骤3:按照定义,结

5、构体对齐模数是结构体内部最大数据成员长度和Jragmaapac中较小者,前者为8后者为4,所以结构体对齐模数是4。sum叮是4的4倍,不需再次对齐。a综上3步,可知结构体的长度是16B,各数据成员在内存中的分布如图1-1所示。a在Linu中计算步骤如下:a步骤1:所有数据成员自身长度和:1B+12B=13B-sum_a=13B步骤2:数据成员a放在相对偏移0处,之前不需要填充字节;数据成员b为了内存对齐,根据“结构体大小的计算方法和步骤”中第二条原则,其对齐模数是4,之前需填充3个字节,sum_a+3=16B-sum_b=16B步骤3:按照定义,结构体对齐模数是结构体内部最大数据成员长度和pr

6、agmapack中较小者,前者为12后者为4,所以结构体对齐模数是4。sum_b是4的4倍,不需再次对齐。综上3步,可知结构体的长度是16B,各数据成员在内存中的分布如图1-2所示。例子2:#pragmapack(2)structmy_structchara;longdoubleb;#pragmapack()例子1和例子2不同之处在于例子2中使用了#pragmapack(2)编译参数,它强制指定对齐模数是2。此例子Windows和Linux计算方法有些许不一致。在Windows中计算步骤如下:步骤1:所有数据成员自身长度和:1B+8B=13B-sum_a=9B步骤2:数据成员a放在相对偏移0处

7、,之前不需要填充字节;数据成员b为了内存对齐,根据“结构体大小的计算方法和步骤”中第二条原则,其对齐模数是2,之前需填充1个字节,sum_a+1=10B-sum_b=10B步骤3:按照定义,结构体对齐模数是结构体内部最大数据成员长度和pragmapack中较小者,前者为8后者为2,所以结构体对齐模数是2。sum_b是2的5倍,不需再次对齐。综上3步,可知结构体的长度是10B,各数据成员在内存中的分布如图2-1所示。在Linux中计算步骤如下:步骤1:所有数据成员自身长度和:1B+12B=13B-sum_a=13B步骤2:数据成员a放在相对偏移0处,之前不需要填充字节;数据成员b为了内存对齐,根

8、据“结构体大小的计算方法和步骤”中第二条原则,其对齐模数是2,之前需填充1个字节,sum_a+1=14B-sum_b=14B步骤3:按照定义,结构体对齐模数是结构体内部最大数据成员长度和pragmapack中较小者,前者为8后者为2,所以结构体对齐模数是2。sum_b是2的7倍,不需再次对齐。综上3步,可知结构体的长度是14B,各数据成员在内存中的分布如图2-2所示。例子3:structmy_structchara;doubleb;charc;前两例中,数据成员在Linux和Windows下都相同,例3中double的对齐模数在Linux中是4,在Windows下是8,针对这种模数不相同的情况

9、加以分析。在Windows中计算步骤如下:步骤1:所有数据成员自身长度和:1B+8B+1B=10B-sum_a=10B步骤2:数据成员a放在相对偏移0处,之前不需要填充字节;数据成员b为了内存对齐,根据“结构体大小的计算方法和步骤”中第二条原则,其对齐模数是8,之前需填充7个字节,sum_a+7=17B-sum_b=17B步骤3:按照定义,结构体对齐模数是结构体内部最大数据成员长度和pragmapack中较小者,前者为8后者为8,所以结构体对齐模数是8。sum_b应该是8的整数倍,所以要在结构体后填充8*3-17=7个字节。综上3步,可知结构体的长度是24B,各数据成员在内存中的分布如图3-1

10、所示。在Linux中计算步骤如下:步骤1:所有数据成员自身长度和:1B+8B+1B=10B,sum_a=10B步骤2:数据成员a放在相对偏移0处,之前不需要填充字节;数据成员b为了内存对齐,根据“结构体大小的计算方法和步骤”中第二条原则,其对齐模数是4,之前需填充3个字节,sum_b=sum_a+3=13B步骤3:按照定义,结构体对齐模数是结构体内部最大数据成员长度和pragmapack中较小者,前者为8后者为4,所以结构体对齐模数是4。sum_b应该是4的整数倍,所以要在结构体后填充4*4-13=3个字节。综上3步,可知结构体的长度是16B,各数据成员在内存中的分布如图3-2所示。例子4:s

11、tructmy_structchara11;intb;charc;此例子Windows和Linux计算方法一样,如下:步骤1:所有数据成员自身长度和:11B+4B+1B=16B-sum_a=16B步骤2:数据成员a放在相对偏移0处,之前不需要填充字节;数据成员b为了内存对齐,根据“结构体大小的计算方法和步骤”中第二条原则,其对齐模数是4,之前需填充3个字节,sum_a+1=17B-sum_b=17B步骤3:按照定义,结构体对齐模数是结构体内部最大数据成员长度和pragmapack中较小者,前者为4后者为4,所以结构体对齐模数是4。sum_b是4的整数倍,需在结构体后填充4*5-17=1个字节。

12、综上3步,可知结构体的长度是20B,各数据成员在内存中的分布如图4所示。例子5:structmy_testintmy_test_a;charmy_test_b;structmy_structstructmy_testa;doublemy_struct_a;intmy_struct_b;charmy_struct_c;例子5和前几个例子均不同,在此例子中我们要计算structmy_struct的大小,而my_struct中嵌套了一个my_test结构体。这种结构体应该如何计算呢?原则是将my_test在my_struct中先展开,然后再计算,即是展开成如下结构体:structmy_structi

13、ntmy_test_a;charmy_test_b;doublemy_struct_a;intmy_struct_b;charmy_struct_c;此例子Windows中的计算方法如下:步骤1:所有数据成员自身长度和:4B+1B+8B+4B+1B=18B-sum_a=18B步骤2:数据成员my_struct_a为了内存对齐,根据“结构体大小的计算方法和步骤”中第二条原则,其对齐模数是8,之前需填充3个字节:sum_a+3=21B-sum_b=21B步骤3:按照定义,结构体对齐模数是结构体内部最大数据成员长度和pragmapack中较小者,前者为8后者为8,所以结构体对齐模数是8。sum_b是

14、8的整数倍,需在结构体后填充3*8-21=3个字节。此例子Linux中的计算方法如下:步骤1:所有数据成员自身长度和:4B+1B+8B+4B+1B=18B,sum_a=18B步骤2:数据成员my_struct_a为了内存对齐,根据“结构体大小的计算方法和步骤”中第二条原则,其对齐模数是4,之前需填充3个字节,sum_b=sum_a+3=21B步骤3:按照定义,结构体对齐模数是结构体内部最大数据成员长度和pragmapack中较小者,前者为4后者为4,所以结构体对齐模数是4。sum_b是4的整数倍,需在结构体后填充6*4-21=3个字节。综上3步,可知结构体的长度是24B,各数据成员在内存中的分

15、布如图5所示。5-源代码附录上面的例子均在Windows(VC+6.0)和Linux(GCC4.1.0)上测试验证。下面是测试程序。#includeintmain()/例子1structmy_structchara;longdoubleb;std:coutexapmle-1:sizeof(my_struct)=sizeof(my_struct)a:%unmy_struct-b:%unsizeof(longdouble):%un,&data.a,&data.b,sizeof(longdouble);/例子2#pragmapack(2)structmy_structchara;longdouble

16、b;#pragmapack()structmy_structdata;std:coutexapmle-2:sizeof(my_struct)=sizeof(my_struct)a:%unmy_struct-b:%unsizeof(longdouble):%un,&data.a,&data.b,sizeof(longdouble);/例子3structmy_structchara;doubleb;charc;structmy_structdata;std:coutexapmle-3:sizeof(my_struct)=sizeof(my_struct)a:%unmy_struct-b:%unmy

17、_struct-c:%un,&data.a,&data.b,&data.c);/例子4structmy_structchara11;intb;charc;std:coutexample-4:sizeof(my_struct)=sizeof(structmy_struct)a:%unmy_struct-b:%unmy_struct-c:%un,&data,&data.b,&data.c);/例子5structmy_testintmy_test_a;charmy_test_b;structmy_structstructmy_testa;doublemy_struct_a;intmy_struct_

18、b;charmy_struct_c;std:coutexample-5:sizeof(my_struct)=sizeof(structmy_struct)my_test_a:%unmy_struct-my_test_b:%unmy_struct-my_struct_a:%unmy_struct-my_struct_b:%unmy_struct-my_struct_c:%un,&data.a.my_test_a,&data.a.my_test_b,&data.my_struct_a,&data.my_struct_b,&data.my_struct_c);return0;扩展:如果结构体包含联合呢?如果联合包含结构体呢?恐怕只有亲gcc下啦!

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!