删除之前指向它的指针后对象会发生什么?
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++ 指针不是智能指针(也许它们是哑指针)并且 delete
ing 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),链表通常不是最佳实现。
这个问题是在我写一个删除双向链表头的函数时产生的,或者更具体地说,我应该问,如果我们在链表中删除指向它的指针,节点会发生什么?
我的函数写成:
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++ 指针不是智能指针(也许它们是哑指针)并且 delete
ing 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),链表通常不是最佳实现。