下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、sizeof(结构体)和内存对齐有的时候,在脑海中停顿了很久的“显而易见”的东西,其实根本上就是错误的。就拿下面的问题来看:struct Tchar ch; i ;使用 sizeof(T),将得到什么样的呢?要是以前,想都不用想,在 32 位机中,是 4个字节,char 是 1 个字节,所以 T 一共是 5 个字节。实践出真知,在 VC6 中测试了下,答案确实 8 个字节。哎,反正受伤的总是我,我已经有点麻木了,还是老老实实的接受吧!为什么和自己有出入呢?这里将引入内存对齐这个概念。许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为
2、4 或 8)的倍数,这就是所谓的内存对齐,而这个 k 则被称为该数据类型的对齐模数(alignment modulus)。当一种类型 S 的对齐模数与另一种类型 T的对齐模数的比值是大于 1 的整数,就称类型 S 的对齐要求比 T 强(严格),而称 T 比 S弱(宽松)。这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以读取数据的速度。比如这么一种处理器,它每次读写内存的时候都从某个 8 倍数的地址开始,一次读出或写入 8 个字节的数据,假如能保证double 类型的数据都从 8 倍数地址开始,那么读或写一个double 类型数据就只需要一次内存操作。否则,就可能需要两次内存操作
3、才能完成这个动作,因为数据或许恰好横跨在两个符合对齐要求的 8 字节内存块上。某些处理器在数据不满足对齐要求的情况下可能会出错,但是el 的 IA32 架构的处理器则不管数据是否对齐都能正确工作。不过el 奉劝大家,如果想数据都应该尽可能地对齐。性能,那么所有的程序ANSI C 标准中并没有规定,相邻的变量在内存中一定要相邻。为了程序的高效性,内存对齐问题由编译器自行灵活处理,这样导致相邻的变量之间可能会有一些填充字节。对于基本数据类型(char),他们占用的内存空间在一个确定硬件系统下有个确定的值,所以,接下来只是考虑结构体成员内存分配情况。Win32下的微软 C 编译器(cl.exe fo
4、r 8086)的对齐策略:1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;备注:编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该基本数据类型所整除的位置,作为结构体的首地址。将这个最宽的基本数据类型的大小作为上面介绍的对齐模数。2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,要编译器会在成员之间加上填充字节( ernal adding);需备注:为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员的整数倍,若是,则存放本成员,反之,则在本成员和上一个成员之间填
5、充一定的字节,以达到整数倍的要求,也就是将预开辟空间的首地址后移几个字节。3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,需要,编译器会在最末一个成员之后加上填充字节(trailing padding)。备注:结构体总大小是包括填充字节,最后一个成员满足上面两条以外,还必须满足第三条,否则就必须在最后填充几个字节以达到本条要求。根据以上准则,在windows 下,使用 VC 编译器,sizeof(T)的大小为 8 个字节。而在 GNU GCC 编译器中,遵循的准则有些区别,对齐模数不是像上面所述的那样,根据最宽的基本数据类型来定。在 GCC 中,对齐模数的准则是:对齐模数最大只能是
6、4,也就是说,即使结构体中有 double 类型,对齐模数还是 4,所以对齐模数只能是 1,2,4。而且在上述的三条中,第 2 条里,offset 必须是成员大小的整数倍,如果这个成员大小=4 则按照上述准则进行,但是如果大于 4 了,则结构体每个成员相对于结构体首地址的偏移量(offset)只能按照是 4 的整数倍来进行判断是否添加填充。看如下例子:struct Tchar ch; double d ;那么在 GCC 下,sizeof(T)应该等于 12 个字节。如果结构体中含有位域(bit-field),那么 VC 中准则又要有所更改:1) 如果相邻位域字段的类型相同,且其位宽之和小于类型
7、的 sizeof 大小,则后面的字段将紧邻前一个字段,直到不能容纳为止;2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的 sizeof 大小,则后面的字段将从新的单元开始,其偏移量为其类型大小的整数倍;3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6 采取不压缩方式(不同位域字段存放在不同的位域类型字节中),Dev-C+和 GCC 都采取压缩方式;备注:当两字段类型不一样的时候,对于不压缩方式,例如:struct Nchar c:2; i:4;依然要满足不含位域结构体内存对齐准则第 2 条,i 成员相对于结构体首地址的偏移应该是4 的整数倍,所以 c 成员后要填充
8、 3 个字节,然后再开辟 4 个字节的空间作为型,其中4 位用来存放 i,所以上面结构体在 VC 中所占空间为 8 个字节;而对于采用压缩方式的编译器来说,遵循不含位域结构体内存对齐准则第 2 条,不同的是,如果填充的 3 个字节能容纳后面成员的位,则压缩到填充字节中,不能容纳,则要单独开辟空间,所以上面结构体N 在 GCC 或者Dev-C+中所占空间应该是 4 个字节。4) 如果位域字段之间穿插着非位域字段,则不进行压缩;备注:结构体 5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。typedef structchar c:2; double i;c2:4;N3;在 GCC 下占据的空间为 16 字节,在 VC 下占据的空间应该是 24 个字节。ps:对齐模数的选择只能是根据基本数据类型,所以对于结构体中嵌套结构体,只能考虑其拆分的基本数据类型。而对于对齐准则中的第 2 条,确是要将整个结构体看成是一个成员,成员大小按照该结构体根据对齐准则判断所得的大小。类
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 【正版授权】 ISO 251:2024 EN Conveyor belts with textile carcass - Widths and lengths
- 湖南文理学院《计算机网络》2022-2023学年第一学期期末试卷
- 湖南农业大学《数据可视化》2021-2022学年第一学期期末试卷
- 2024至2030年中国片式圆网行业投资前景及策略咨询研究报告
- 院团委组织部月工作计划范文
- 2024至2030年中国球形封头反应釜行业投资前景及策略咨询研究报告
- 2024至2030年中国喷漆展柜行业投资前景及策略咨询研究报告
- 2024年中国铆接桥架市场调查研究报告
- 2024至2030年中国透水单壁波纹管行业投资前景及策略咨询研究报告
- 2024至2030年中国电镀塑胶壳行业投资前景及策略咨询研究报告
- 《2024年 电力展厅策划方案范文模板》范文
- DB34∕T 2937-2017 霍山铁皮石斛枫斗质量检测技术规程
- 招聘笔试题与参考答案(某世界500强集团)2024年
- SLT824-2024 水利工程建设项目文件收集与归档规范
- 2024年政法干警 公安之公安基础知识考试题库
- 婴幼儿发展引导员理论考试题库资料500题(含答案)
- 智能硬件设备项目创业计划书
- DL∕T 1910-2018 配电网分布式馈线自动化技术规范
- 形式与政策附有答案
- 公文写作题库(500道)
- 2024(新增)异常工况安全处置管理制度
评论
0/150
提交评论