在析构函数被调用后悬空指针

时间:2016-12-19 04:50:32

标签: c++ pointers

我经历了this post并且有疑问。在析构函数中取消对象元素是一个好习惯吗? 当对象超出范围时将调用析构函数,但是在析构函数中需要将其元素设置为NULL以确保不会留下悬空指针。

3 个答案:

答案 0 :(得分:1)

对象被销毁后,它就不复存在了。当这些值立即停止存在时,将其成员设置为特定值是毫无意义的。

NULL指向它们的对象时,设置指向delete的模式是非常有害的并且在过去导致错误。除非有特定原因指针需要设置为NULL(例如,稍后可能会针对NULL对其进行测试),否则会被设置到NULL

考虑:

Foo* foo getFoo();
if (foo!=NULL)
{
    do_stuff();
    delete foo;
}
// lots more code
return (foo == NULL);

现在,假设有人在此代码中foo = NULL;之后添加delete foo;,认为您应该这样做。现在代码将给出错误的返回值。

接下来,请考虑一下:

Foo* foo getFoo();
Foo* bar = null;
if (foo != NULL)
{
    bar = foo;
    do_stuff(bar);
    delete bar;
    bar = NULL;
}
// lots more code
delete foo;

我们总是在NULL之后设置指向delete的指针,因此delete foo;必须是安全的,对吧?显然它不是。因此,在NULL之后设置指向delete的指针既不必要也不充分。

不要这样做。

答案 1 :(得分:0)

没有必要在析构函数中将成员元素设置为NULL,因为已在所有者对象上调用了delete,以便调用该析构函数。删除对象的代码负责不再尝试访问该对象的内容。

您还在使用额外的周期来清除该内存。

答案 2 :(得分:0)

这样做的目的是在发生编程错误时提供确定性行为。

  • 如果使用了删除的指针,则程序将在取消引用nullptr时始终失败。 (不允许程序继续。)
  • 如果删除的指针设置为nullptr然后再次删除,则第二次尝试是noop(按设计)。

这是在析构函数中未删除的指针的正常模式。 (聪明的指针是你的朋友,完全避免这种情况。)

在析构函数中清空已删除的成员指针的目的不太明显;当怀疑其他代码可能引用该成员时。通常应该避免这种情况(依赖于此),因为一旦回收了破坏类的内存,它就具有有限的效用。虽然依赖于实现,但在许多环境中,内存可以活得足够长,导致程序在重新使用已删除的内存时失败,以便程序员可以找到问题并修复它。