//日期:2009.03.20
//作者:goodshell
//转载请注明来源:http://blog.youkuaiyun.com/goodshell
关于在堆中申请内存的思考
今天给同学演示关于在堆、栈中申请内存的区别,顺便解决了一下自己的问题,如下。
问题:C中的malloc()和free()、C++中的new和delete相信大家都很熟悉了,但这些函数和操作符究竟为我们做了什么呢?分配的内存真的等于我们想要的大小吗?
看下面的程序段:
现在看一下输出(实际是就是我们刚才申请的内存区),或许我们能从中看出点什么:
-----------------------
6 7 8 9
-3 -3 -3 -3
0 0 0 0
0 0 0 0
7 0 7 0
35 1 8 0
64 33 55 0
-80 33 55 0
0 0 0 0
0 0 0 0
4 0 0 0
1 0 0 0
45 0 0 0
-3 -3 -3 -3
1 2 3 4
-3 -3 -3 -3
0 0 0 0
-----------------------
在上面的程序中我们申请了两块内存,都是4个字节,从上面的内存中我们就很容易分辨出来,6789和1234两块内存。对于我们申请 p2= new char [4]这部分内存,实际上申请的并不只是4个字节,除了我们要求的1234这4个字节,另外还分配了13*4=52个字节的内存。在我们真正需要的数据的前后,都有4个字节的-3,我推断这个很可能是分界符吧,用来标识我们所申请内存的起始和结束位置。 从我们想要的内存数据开始向上数16个字节值是“4”,这个正是我们分配的内存区的大小。当改变申请的内存区的大小时,这个值也要相应地发生改变,验证了刚才的推断。
以前我们可能就有这样的疑问,为什么要释放内存时只把指针传给delete或free()就可以了,或许我们能从这多出来的内存区里找到答案。我现在猜想应该是这个额外分配的内存的缘故,当然,现在只是猜想而已。
但真的是一定多分配52个字节吗,似乎不是这样,现在我们把上面的程序改一下
这时内存的内容如下,
-----------------------
6 0 0 0
7 0 0 0
8 0 0 0
9 0 0 0
-3 -3 -3 -3
0 0 0 0
0 0 0 0
0 0 0 0
9 0 9 0
86 1 8 0
64 33 55 0
-48 33 55 0
0 0 0 0
0 0 0 0
16 0 0 0
1 0 0 0
45 0 0 0
-3 -3 -3 -3
1 0 0 0
2 0 0 0
3 0 0 0
4 0 0 0
-3 -3 -3 -3
-----------------------
可以看到,这时多分配的内存大小是14*4=56个字节,为何要这样,我现在也没有搞明白,但或许我们能从《操作系统》这本书里找到答案。但是,我们上面总结的规律在这里似乎还是有效的,即4个-3作为分界符,申请的内存大小是从我们想要的内存数据开始向上数16个字节的值来标识的(或许不只这一个字节,而是从这个字节开始的连续4个字节做为一个int型数据来决定的)。
以上仅是拙见而已,还请大家多多指正。