为啥建议删除后将指针设置为null? [复制]

Posted

技术标签:

【中文标题】为啥建议删除后将指针设置为null? [复制]【英文标题】:Why is it recommended to set a pointer to null after deleting it? [duplicate]为什么建议删除后将指针设置为null? [复制] 【发布时间】:2013-05-10 12:13:39 【问题描述】:
int* ptr = new int();
delete ptr; 
ptr = 0; // or null

我的书告诉我,在删除指针指向的内容后将指针设置为 null 或 0 是一种很好的做法。我不明白为什么。有人可以给我一个可能导致问题的场景吗?

【问题讨论】:

相关帖子:***.com/questions/1931126/…, ***.com/questions/14416676/… 很多原因。我认为 最强 的原因只是“良好实践”:) 其他原因包括 1)意图清晰,2)易于调试(空指针更容易看到),3)更好的错误处理(空指针会更快崩溃,“初始化的垃圾指针”可能会稍后崩溃)等等等等 重要的一点:做它(确保尽可能认真地清空你的指针),但不要依赖它(只是因为指针 isn't null 并不意味着它一定是 valid)。恕我直言... @paulsm4:我认为这是不好的做法。它隐藏的问题多于解决的问题。它还会导致将导致崩溃的问题移至代码中的其他位置(并且仍然崩溃),但现在您很难追踪原始问题。不要这样做。不好的做法。唯一好的做法是确保任何被删除的变量立即离开作用域,因此不会不可用。 找另一本书。管理指针需要仔细设计,而不是本地黑客。例如:int *p = new int; int *q = p; delete p; p = 0; 你猜怎么着? if(q) 不会在这里救你。 【参考方案1】:

只是为了让您知道指针不再指向任何东西,并且如果条件和其他布尔检查将失败:

   delete ptr;
   ptr = NULL;
   if(ptr)
     *ptr = 2;

此代码将运行得非常好,但如果指针未设置为 NULL 会导致内存损坏。

【讨论】:

您能否详细说明它会如何导致内存损坏?如果 ptr 没有设置为 null,*ptr = 2 不会只是指向 2 吗?问题出在哪里? 既然可以使用智能指针,为什么还要使用指针? 当你调用delete时,delete不会改变你指针的地址。因此,如果您访问该地址并对其进行写入,您将写入已删除的内存。【参考方案2】:

这样,如果您稍后在程序中不小心再次使用ptr,它会立即导致崩溃,而不是在程序中导致难以发现的错误。

【讨论】:

【参考方案3】:

如果您在代码的其他地方引用该指针怎么办?

许多开发人员使用简单的检查来确保他们仍然可以访问该指针。

int * blah = new int();

void changeBlah( void )
  
  if( blah )
  
    *blah = 1337;
  

稍后,如果您在指针上调用 delete,您可能仍会调用更改存储在指针中的值的函数。

delete blah;
changeBlah();

这个函数会运行并变得未定义,就像你在你不拥有的内存上写一样。

delete blah;
blah = 0;
changeBlah();

现在代码可以毫无问题地运行了。

【讨论】:

多么棒的答案。【参考方案4】:

因为删除空指针总是安全的。这是为了避免双重删除错误。开发者还使用它来检查指针是否已经被删除。

【讨论】:

【参考方案5】:

如果在删除后总是将其设置为 0,则可以在取消引用之前使用它来检查指针是否有效。所以无论你在哪里使用它,你都可以检查如下:

if(myPointer)
  value = *myPointer;

如果你在删除的时候没有设置为0,就永远不能使用这种构造。

【讨论】:

以上是关于为啥建议删除后将指针设置为null? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

释放堆内存后将指针设置为 NULL [重复]

free() 在 c 代码和代码中收集垃圾值即使在释放后将指针设置为 NULL 也不起作用

为啥 delete 不将指针设置为 NULL?

在 free() 之后将指针设置为 NULL 总是一个好习惯吗? [复制]

我应该在删除后分配我的指针 0 吗? [复制]

深层复制构造函数--初识