关于struct类型的sizeof探究
2016-04-06 15:36
369 查看
关于struct类型的sizeof探究
1、struct类型字节对齐先来看一个例子1 2 3 4 5 6 7 | struct db { char c1; int i1; char c2; float f; }; |
但是需要强调的是,每个成员有其自己的对其方式,结构体本身也有对其方式。下面看这个例子:看看它占用多少字节。
1 2 3 4 5 6 | struct db { char c1; int i1; char c2; }; |
最后再试试看下面这个结构体占用字节会是多少?
1 2 3 4 5 6 | struct db { char c1; char c2; char c3; }; |
2、关于double类型出现在struct里面
先看下例
1 2 3 4 5 6 7 | struct db { char c1; int i1; float f; double d1; }; |
然后后来我实验了好几个例子,都是这种情况,所以目前我就这么下一个结论吧:可能是在x86下最大的对齐字节数也就是4了,因为当 用语句 #pragma pack(2) 限定对齐方式小于4的时候都可以达到目的,一旦超过4就无效了。(谁有更好的解释希望拿出来分享啊~)
3、为什么要对齐?
(摘自网上博客http://www.cppblog.com/snailcong/archive/2009/03/16/76705.html)
内存对齐的主要作用是:
1)平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2)性能原因:经过内存对齐后,CPU的内存访问速度大大提升。具体原因稍后解释。
看下图:
图一:
这是普通程序员心目中的内存印象,由一个个的字节组成,而CPU并不是这么看待的。
图二:
CPU把内存当成是一块一块的,块的大小可以是2,4,8,16字节大小,因此CPU在读取内存时是一块一块进行读取的。块大小成为memory
accessgranularity(粒度) 本人把它翻译为“内存读取粒度”。
假设CPU要读取一个int型4字节大小的数据到寄存器中,分两种情况讨论:
1、数据从0字节开始
2、数据从1字节开始
再次假设内存读取粒度为4。
图三:
当该数据是从0字节开始时,很CPU只需读取内存一次即可把这4字节的数据完全读取到寄存器中。
当该数据是从1字节开始时,问题变的有些复杂,此时该int型数据不是位于内存读取边界上,这就是一类内存未对齐的数据。
图四:
此时CPU先访问一次内存,读取0—3字节的数据进寄存器,并再次读取4—5字节的数据进寄存器,接着把0字节和6,7,8字节的数据剔除,最后合并1,2,3,4字节的数据进寄存器。对一个内存未对齐的数据进行了这么多额外的操作,大大降低了CPU性能。
这还属于乐观情况了,上文提到内存对齐的作用之一为平台的移植原因,因为以上操作只有有部分CPU肯干,其他一部分CPU遇到未对齐边界就直接罢工了。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- C#中struct和class的区别详解
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C#中sizeof的用法实例分析
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例