荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Dreamer (黄昏·落霞·萤火·街灯), 信区: SoftDev
标  题: 【C++】[FAQ]为何delete操作不把指针置零?
发信站: 荔园晨风BBS站 (Mon Jun 14 14:01:30 2004), 站内信件


Q: 为何delete操作不把指针置零?
A: 嗯,问得挺有道理的。我们来看:
delete p;
// ...
delete p;


如果代码中的//...部分没有再次给p分配内存,那么这段代码就对同一片内存释放
了两次。这是个严重的错误,可惜C++无法有效地阻止你写这种代码。不过,我们
都知道,释放空指针是无危害的,所以如果在每一个delete p;后面都紧接一个p =
 0;,那么两次释放同一片内存的错误就不会发生了。尽管如此,在C++中没有任何
语法可以强制程序员在释放指针后立刻将该指针归零。所以,看来避免犯这样的错
误的重任只能全落在程序员肩上了。或许,delete自动把指针归零真是个好主意?

哦,不不,这个主意不够“好”。一个理由是,被delete的指针未必是左值。我们
来看:

delete p+1;
delete f(x);


你让delete把什么自动置零?也许这样的例子不常见,但足可证明“delete自动把
指针归零”并不保险。[译注:事实上,我们真正想要的是:“任何指向被释放的
内存区域的指针都被自动归零”——但可惜除了Garbage Collector外没什么东东
可以做到这点。] 再来看个简单例子:
T* p = new T;
T* q = p;
delete p;
delete q; // ouch!


C++标准其实允许编译器实作为“自动把传给delete的左值置零”,我也希望编译
器厂商这样做,但看来厂商们并不喜欢这样。一个理由就是上述例子——第3行语
句如果delete把p自动置零了又如何呢?q又没有被自动置零,第4行照样出错。
如果你觉得释放内存时把指针置零很重要,那么不妨写这样一个destroy函数:

template<class T> inline void destroy(T*& p) { delete p; p = 0; }

不妨把delete带来的麻烦看作“尽量少用new/delete,多用标准库中的容器”之另
一条理由吧 :O)

请注意,把指针作为引用传递(以便delete可以把指针置零)会带来额外的效益—
—防止右值被传递给destroy() :

int* f();
int* p;
// ...
destroy(f()); // error: trying to pass an rvalue by non-const
reference
destroy(p+1); // error: trying to pass an rvalue by non-const
reference




--

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.0.223]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店