读书人

关于构造体的内存空间使用

发布时间: 2012-07-30 16:19:05 作者: rapoo

关于结构体的内存空间使用

有些朋友会遇到一些面试题,关于某个结构体暂用多少内存的问题,不知道的会斩钉截铁的计算成员变量尺寸总和

菜鸟一点的直接慌了,这么简单应该暗藏杀机,我们举个例子吧


有屎以来最大的疑惑,让人大吃一斤啊!


我们先看第一条分割线以上的部分,Cube的内存大小不是7而是8,Cuber更加,不是9而是12.

数学极度牛插的你很快会发现他们都是4的倍数,莫非32位系统下按32位来分配内存?

可以这么理解,其实这是一个概念,叫内存对齐,一般开发软件几乎不需要理会它,由编译器自己去搞定,也就是术语所说的对开发人员透明.

我这里所说的,是因为有些同志不习惯用sizeof,而喜欢直接用数字,比如将Cube结构写入文件:

fwrite(&Cube, sizeof(Cube), 1, pf);

即从Cube的内存地址开始,写入1个Cube结构大小的数据到pf指针指向的文件.然而很多同志喜欢这样:

fwrite(&Cube, 7, 1, pf);

其实这样问题不太大,但如果是Cuber,那么Cuber.Integer就丢失了最高位1个字节!!!

那么,每次调用sizeof(),这个是不是函数啊?调用函数,我记得大侠你说过要push ebp什么的一堆寄存器操作,效率降低哇!

我们看看,反汇编:

关于构造体的内存空间使用

看到了吧,C/C++函数的调用是从右向左依次将函数压入堆栈的,这里并没有call sizeof的痕迹,直接是8!所以并不影响程序的效率.

那么为什么是一定要对齐呢?那不是浪费吗?原因上面已经给出一部分了.内存对齐后程序的内存访问效率会得到提升(也有一说Pentium以后的CPU是一样的)

至少32位下(乃至64位CPU在32位系统下是这样的).上面有个函数需要解释一下:

inline QWORD fnGetCycleUnit()

当然,QWORD你知道的,最上面已经定义了是unsigned __int64,是否需要64位cpu支持,我不知道,我的是,个人觉得应该不需要.

可是,这个函数没有返回值哇???其实函数体里面的机器码是执行一条x86指令:rdtsc,因为据说内联汇编不支持,所以直接用机器码.

rdtsc会把64位的CPU振荡周期计数填充到edx和eax两个寄存器中,edx保存高32位,而正好,这两个寄存器是VC中函数返回值存放的地方,所以不需要return;

关于构造体的内存空间使用

然后是,对于几个内存的访问,虽然是好几条指令,但是对于主频3.0GHz的CPU就像人的一生对于130多亿年的宇宙历史,实在是沧海一粟!

而且,这个东西稳定性很差,CPU温度,甚至你摸一下键盘都可能影响它得到的值...所以我才用N次实验取平均的统计法来计算.

结果你也看到了...

文章随便写写,也花很多时间和经历,随便看看,如过眼云烟.不过希望大家多用sizeof().

就这样吧

读书人网 >编程

热点推荐