网页
资讯
视频
图片
知道
文库
贴吧
地图
采购
进入贴吧
全吧搜索
吧内搜索
搜贴
搜人
进吧
搜标签
日
一
二
三
四
五
六
签到排名:今日本吧第
个签到,
本吧因你更精彩,明天继续来努力!
本吧签到人数:0
一键签到
成为超级会员,使用一键签到
一键签到
本月漏签
0
次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行
补签
。
连续签到:
天 累计签到:
天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
01月04日
漏签
0
天
cpp吧
关注:
903
贴子:
1,479
看贴
图片
吧主推荐
游戏
7
回复贴,共
1
页
<<返回cpp吧
>0< 加载中...
C语言free释放内存后为什么指针里的值不变?竟然还可以输出?
取消只看楼主
收藏
回复
山石榴树之恋
六年级
9
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
想必大家都知道C语言中动态开辟内存之后,必须要释放内存,来防止内存泄露。也就是malloc之后,必须要free。正所谓”有借有还,再借不难”, 不少同学会问为什么释放指针后,指向这块内存的指针的值不变呢,我们今天为大家揭秘。
山石榴树之恋
六年级
9
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
首先,我们用malloc开辟一个内存,用strcpy拷贝一串字符串,然后释放掉,通过断点调试进行观察!
下图可以看到,在VC6编译环境下,观察指针p的指针所指向的内容已经被strcpy后改变
山石榴树之恋
六年级
9
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
下一步free函数,我们选择F11单步介入观察,幸运的是在VC6中可以看到源代码,如下图,会进入到DBGHEAP.c文件中,会调用_free_dbg函数,继续F11介入观察代码
山石榴树之恋
六年级
9
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
多次单步之后,我们可以看到一个memset函数,那么F10执行这memset,观察P指向的内容,果然不出我们所料:
0x00970e38处的内容已经被0xDD覆盖,如下图红色字部分。
山石榴树之恋
六年级
9
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
这里重点观察了,这个memset函数我们应该很熟悉,第二个参数即为要重置的内容,这里我们可以转到定义 处,或者搜索第二个参数_bDeadLandFill,可以看到有如下定义, 为0xDD
山石榴树之恋
六年级
9
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
怎么样,大家看到这里应该明白了吧!
我们这里是VC6编译器下的环境,也有部分同学反映free之后内容并未消失,这里我们分析可能是部分编译器free函数实现原理不同,欢迎大家自行尝试,并与我们交流。
而关于free之后,p的之后为何没有改变,仍然还是这个原先堆空间的这个地址,原因在于free函数仅仅是将malloc申请的内存释放回去,所谓的释放也就是告诉编译器,这块内存已经使用完毕,可以收回了。但指针所指向的内存值,并不会发生改变。就可以比方说,你租了一套房子,到期后,房子收回归还房东,而此时你可能还拿着房子的钥匙,这个时候你虽然可以继续访问这个房子(内存),但已经不属于你,是非法的。也可能有新的租客入驻更改房子的内置,也可能还是这个样子。取决于不同的房东(编译器)和租客(内容)。
这就是free释放内存后,指针内地址仍然存在,但有时还可以访问,有时候访问输出乱码或输出其他值的原因。
怎么样,大家明白了吗?
有任何问题,或新的发现,欢迎联系我们!
C语言研究中心
山石榴树之恋
六年级
9
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
这么好的文章没人???
山石榴树之恋
六年级
9
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
更多干货可以看看dotcpp
登录百度账号
扫二维码下载贴吧客户端
下载贴吧APP
看高清直播、视频!
贴吧页面意见反馈
违规贴吧举报反馈通道
贴吧违规信息处理公示