免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: slow_hand
打印 上一主题 下一主题

为什么free或者delete的时候不直接将指针置成NULL? [复制链接]

论坛徽章:
0
21 [报告]
发表于 2009-11-27 10:59 |显示全部楼层
原帖由 sinall 于 2009-11-27 09:10 发表
楼主,想必经济学十大原理可以回答您的问题。
“人们面临权衡取舍”
关于作出决策的第一课可以归纳为一句谚语:“天下没有白吃的午餐。”为了得到我们喜爱的一件东西,通常就不得不放弃另一件我们喜爱的东西。作出决策要求我们在一个目标与另一个目标之间有所取舍。

也可以从哲学的角度看看这个问题。
“矛盾时时处处存在”
矛盾中的双方,对立、斗争、作用、转换。
这就是为什么后来的Java、C#之类的语言解决了你的问题。

是的,经济学和哲学感觉是万金油啊。呵呵

论坛徽章:
0
22 [报告]
发表于 2009-11-27 20:53 |显示全部楼层
原帖由 shan_ghost 于 2009-11-27 15:54 发表
想全自动的话可以用VB

不过,当年的VB为了初学者方便到处修扶手,后果是混乱到连微软自己都受不了,以至于从VS.NET开始彻底重做,又把扶手全拆了。

我当年维护过十几万行的TCL工程,后果是被这种语言的诸 ...

这位仁兄估计是经过长期在程序设计中的浸润,才有这么多的体会。佩服!

论坛徽章:
0
23 [报告]
发表于 2009-11-27 21:27 |显示全部楼层
原帖由 lemoncookie 于 2009-11-27 18:32 发表
不算复杂的一个问题
结果说什么的都有

“野指针”本身就是一个不严格的“野”说法,简单地就认为是指向已经释放的内存空间的指针吧
问题是,当前程序中有多少个指针指向这个释放的空间?(包括不指向头部, ...

另外,很多网友提到,因为free函数的值传递,不能实现在free函数内部对指针的NULL赋值。这是因为free的原始版本就没想过要NULL赋值,当然就有这个问题,对吧。
还有我觉得,不能把“野指针”的范围说的那么大。有的时候,虽然你把已经释放了的内存指针赋给了另外一个副本,也没太大关系。因为这个指针只是一个栈上的变量,出了作用域,就引用不到它了。这就是一般的程序错误了。

论坛徽章:
0
24 [报告]
发表于 2009-11-30 19:12 |显示全部楼层
原帖由 ilovedrv 于 2009-11-30 15:07 发表
看到这贴里面的很多回答, 感觉根本就没有弄懂什么是指针

那这位小哥给讲讲到底啥是指针,指针的本质是什么吧。呵呵。

论坛徽章:
0
25 [报告]
发表于 2009-12-01 20:01 |显示全部楼层
1.增加系统额外开销。
原来在free函数里面,p是在栈里面的数据,在执行到free以后,这个值基本上都是在cache里面进行缓冲;

修改后,访问内存变成二级内存访问,首先访问栈里面的p,然后根据p里面的内容作为地址再访问内存,这部分内存有可能不在cache中,执行完free以后,还需要把这块数据回写到内存。

由于free被执行的非常频繁,所以这些额外的系统开销也是需要考虑的。

不知道一级访问和二级访问的开销差别有多大。但如果程序中大量使用动态分配内存的话,应该确实要考虑到这方面的影响。

2.修改后,增加了free执行出错的可能,因为p有可能指向一个非法地址,所以free函数执行的时候有可能出现非法内存访问错误。

p是一级和二级的都有可能是非法地址,对吧

3.由于C里面允许多个指针变量指向同一个地址,对于初学者来说,free以后,那些情况下应该将指针置NULL,那些情况下不用将指针置NULL将会变成一个噩梦。

来这里讨论的大部分都是有经验的程序员,至少对C语言还比较熟悉,觉得改变一下也不是不能适应。但是老师教学生的时候,就会变得非常复杂。

现在,只要说free以后,不会将指针置NULL,需要程序员手工来置NULL。
修改后呢,老师要花费很多时间,一一举例,说明那些情况下,free一块内存以后,不需要将指针置NULL,那些情况下,free以后需要将内存置NULL。

一般指针都是声明的时候,立马初始化为NULL,然后该怎么就怎么用,用完后不一定要赋值成NULL吧。

4.即使是有经验的程序员,在使用free的时候也需要非常谨慎。
在稍微复杂一点儿的项目里面,各种数据结构中,都会用到指针变量,偶尔也会出现多个指针指向同一个内存地址的情况,而且为了简化代码,很多时候会用一个指针变量来代替直接使用一个结构的指针,例如
struct CC c = b->a;
然后使用c变量来完成各个操作,在释放的时候,也是free(c);b->a=NULL;
如果修改以后,每次free的时候,同样要考虑很多事情,free里面的参数要使用那个变量,还有没有其他变量指向这个地址,需要在free的时候置NULL。

至少我认为现在的方式,我有free以后,会考虑一下那些值需要设置NULL的习惯。如果大部分时间不需要设置NULL,只有在极少部分的情况下需要设置NULL,我估计不会养成free的时候思考这些问题的习惯。

我现在觉得free的时候把指针赋值成NULL真的没有太大意义,因为赋值成NULL,为了是怕访问已释放了的堆内存,但如果你不去用的话(或者说不错用的话),即使不赋值成NULL,也没问题。赋值成NULL只能说是一种好的编码习惯。
另外struct CC c = b->a; 应该是struct CC *c = b->a;吧?

[ 本帖最后由 slow_hand 于 2009-12-1 20:17 编辑 ]

论坛徽章:
0
26 [报告]
发表于 2009-12-02 11:23 |显示全部楼层
原帖由 langue 于 2009-12-2 00:52 发表
这个世界是无情的。

设计成不置空,有人骂。
设计成直接置空,还是有人骂。
设计者大吼一声:烦死了!你们爱怎么玩怎么玩去!

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP