关于结构体的内存空间使用
有些朋友会遇到一些面试题,关于某个结构体暂用多少内存的问题,不知道的会斩钉截铁的计算成员变量尺寸总和
菜鸟一点的直接慌了,这么简单应该暗藏杀机,我们举个例子吧
有屎以来最大的疑惑,让人大吃一斤啊!
我们先看第一条分割线以上的部分,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().
就这样吧