想必大家都知道C语言中动态开辟内存之后,必须要释放内存,来防止内存泄露。也就是malloc之后,必须要free。正所谓”有借有还,再借不难”, 不少同学会问为什么释放指针后,指向这块内存的指针的值不变呢,我们今天为大家揭秘。
首先,我们用malloc开辟一个内存,用strcpy拷贝一串字符串,然后释放掉,通过断点调试进行观察!
下图可以看到,在VC6编译环境下,观察指针p的指针所指向的内容已经被strcpy后改变
下一步free函数,我们选择F11单步介入观察,幸运的是在VC6中可以看到源代码,如下图,会进入到DBGHEAP.c文件中,会调用_free_dbg函数,继续F11介入观察代码
多次单步之后,我们可以看到一个memset函数,那么F10执行这memset,观察P指向的内容,果然不出我们所料:
0x00970e38处的内容已经被0xDD覆盖,如下图红色字部分。
这里重点观察了,这个memset函数我们应该很熟悉,第二个参数即为要重置的内容,这里我们可以转到定义 处,或者搜索第二个参数_bDeadLandFill,可以看到有如下定义, 为0xDD
怎么样,大家看到这里应该明白了吧!
我们这里是VC6编译器下的环境,也有部分同学反映free之后内容并未消失,这里我们分析可能是部分编译器free函数实现原理不同,欢迎大家自行尝试,并与我们交流。
而关于free之后,p的之后为何没有改变,仍然还是这个原先堆空间的这个地址,原因在于free函数仅仅是将malloc申请的内存释放回去,所谓的释放也就是告诉编译器,这块内存已经使用完毕,可以收回了。但指针所指向的内存值,并不会发生改变。就可以比方说,你租了一套房子,到期后,房子收回归还房东,而此时你可能还拿着房子的钥匙,这个时候你虽然可以继续访问这个房子(内存),但已经不属于你,是非法的。也可能有新的租客入驻更改房子的内置,也可能还是这个样子。取决于不同的房东(编译器)和租客(内容)。
这就是free释放内存后,指针内地址仍然存在,但有时还可以访问,有时候访问输出乱码或输出其他值的原因。
怎么样,大家明白了吗?
有任何问题,或新的发现,欢迎联系我们!
C语言研究中心(www.dotcpp.com)