删除之前指向它的指针后对象会发生什么?

What happens to the object after deleting the pointer which previously pointed to it?

这个问题是在我写一个删除双向链表头的函数时产生的,或者更具体地说,我应该问,如果我们在链表中删除指向它的指针,节点会发生什么?

我的函数写成:

void remHead(){
    Node* tmp = head->next;
    tmp->prev = NULL;
    delete head;
    head = tmp;
}

我问这个问题是因为在我的代码中,我只是让双向链表中的第二个节点prev指向NULL,并删除指向头部的指针,并将其重新分配给新的头部。

我忽略的(我认为)是我没有让原来的 head->next 指向 NULL,因为我想知道我们是否只是删除了 head 指针,它的字段(如上一个,下一个)也会被删除吗?是这样吗?它会不会导致任何错误,因为如果不是这样,原来的 head 的 next 将指向新的 head?

感谢您的澄清。

好吧,什么也没有发生,当您调用 free/delete 时,head 元素的内存将被释放,无论其内容如何。 C/C++ 不会 'follow' 指针会执行深度资源释放(如果这是您的问题),因此无需担心。 顺便说一句,通常,它是泄漏的来源,因为人们 应该 执行深度发布,但他们忘记了(认为这是自动完成的)

默认情况下,没有任何反应。默认的 c++ 指针不跟踪 "lost" 对象,但是从 c++11 开始有一个解决方案。

<memory>Cpp reference

中声明了几种智能指针类型

该曲目 "ghost objects" 并删除它们。

为了清楚起见,假设您有:

class Node {
    /*...*/
    Node* prev;
    Node* next;
    /*...*/
};

C++ 指针不是智能指针(也许它们是哑指针)并且 deleteing a Node 不会对 prev 指向的对象做任何事情并且next.

那是除非你实现了一个析构函数 ~Node() 来执行诸如 delete next;.

之类的事情

这将导致级联删除链,在您尝试删除单个节点的情况下,您必须小心设置 node->next=nullptr

如果您还包括 delete prev,您也会遇到麻烦,因为它会导致节点删除已经 delete 调用它们的节点(并且正在销毁和调用delete在手头的节点上。

出于这个原因,链表实现往往不会在节点中放置所有权并在列表中实现过度所有权:

~List(){
   Node*curr{head};
   while(curr!=nullptr){
       auto next{curr->next};
       delete curr;
       curr=next;
   }
}

如果你想要一个对象指向另一个对象 delete 另一个它指向破坏现代最佳实践是使用 std::unique_ptr<>:

那就是:

#include <memory>
/*...*/

class Node {
    /*...*/
    Node* prev;
    std::unique_ptr<Node> next;
    /*...*/
};

但如前所述,如果您进行任何编辑 (removing/splicing),链表通常不是最佳实现。