最近看了一篇手机上某个前辈的文章,他描述了一下,关于在VC下面内存的分配,同一个类或者说结构体完全相同的成员,调整它们的位置竟然可以减少内存的分配。当时笔者匆忙看了一眼,大概记住了一下。回到家中打开了电脑试了一下,但是貌似那位前辈的好像有点问题。并不是全部都对。那么那位前辈是怎么说的呢?大概的意思是这样的:
操作系统分配内存的方法是按照你的定义顺序,从第2个开始,你给整个类或者方法前面的内存大小一定是新分配成员变量的内存大小的倍数。什么意思。打个比方。
V 1
class Tes{ char a;//占1个字节 int b;//占4个字节 double c;//占8个字节 };
我们应该知道char占1个字节,int占4个字节,double占8个字节。操作系统首先给Tes分配内存,看见了a,它是第1个,所以直接给Tes分配了1个字节,然后是给b分配,因为前面分配的是1,明显不是4的整数,所以系统默认给Tes的后面又多划分的3个字节(不放东西在里面),这就凑够了4个字节,刚好是b的一倍。然后是给c分配8给字节,前面a分配了1个字节加上了多于的3个字节,b也有4个字节刚好是8个字节。这样系统有分给了Tes 8个字节,共计16个字节。我们可以调整发现如果你的代码同样的内容却分配的大小不一。看代码V 2
class TesA{ int b; double c; char a; }
按照我们前面的规则,他的大小应该是 b:4+凑数: 4 + c:8+a:1=17的。同样的代码,这样就发现怎么V 2比V 1多分配了1给字节。当然一开始我没学过,回家就把代码给敲了上去,试了。发现V 2的大小比V 1确实大了,但是不是大了1而是大了8个字节。我了个乖乖。这就表明同样的代码不同的布局还真就有不同的反应啊。到底是怎么分配的呢?别急,我下面来讨论讨论。
软件环境 VC++6.0操作系统32位xp.
首先我们来变一下出现代码V 3
class TesB{ int b; double c; char a; char a1; }
当然我在V3中发现了有点怪异,我们再加点。代码V4
class TestC{ int b; double c; char a; char a1; char a2; char a3; char a4; char a5; char a6l; char a7; char a8; };
在增加了这么多代码,我们在来看看Main函数
void main(){ cout<<sizeof(Tes)<<endl; cout<<sizeof(TesA)<<endl; cout<<sizeof(TesB)<<endl; cout<<sizeof(TesC)<<endl; }
他们的结果是
16 24 24 32
我们来看一下,从4个数字我们来看,首先第1个是在我们预期,后面的则不是。我们比较TesB和TesC发现,只有代码char增加了8个申请的内存才会有变化,也就是说,系统每次分配的内存不是像我们前面的前辈说的那样。编译器最后会看,你整个的类或者结构体的大小是否为其中(最长的)成员变量的最大值,如果不是,系统会自动扩充。就那V3来看本来应该是18的,但是因为18不是8的整数倍,所以就扩张到了24.