我目前正在尝试为链表类制作自己的析构函数,我知道我不能删除析构函数中的头,因为curr在上面的代码中使用了它,但不删除头会导致我的代码中内存泄漏吗?我甚至需要将head设置为null吗?
~LinkedList(){//Destructor
Node*curr = head;
Node* next = nullptr;
while(curr->next != nullptr){
next = curr->next;
delete curr;
curr = next;
}
head = nullptr;
cout<<"Destructor called"<<endl;
}
我知道我不能删除析构函数中的头,因为curr在上面的代码中使用了它
那么你所知道的是错误的,因为你可以并且必须释放head
节点,否则如果列表不为空,它就会被泄露。仅仅因为curr
指向head
节点并不意味着您不能释放该节点。只是不要再使用该指针,直到您将其重新分配到另一个有效节点。
但是删除头不会导致我的代码内存泄漏吗?
是。
我甚至需要将head设置为null吗?
这不是严格需要的,不是。但它也不会伤害任何东西。由于被销毁的对象对外部世界来说实际上是死的,因此外部代码对它的任何进一步访问都是未定义的行为,无论您是否将其head
成员设置为nullptr
。
也就是说,你显示的代码很好,除了一个小错误:
while(curr->next != nullptr)
需要改为:
while(curr != nullptr)
在原始代码中,如果列表为空,则curr
将为nullptr
,因此访问curr->next
将是未定义的行为。如果列表不为空,则循环将跳过释放列表中curr->next
将为nullptr
的最后一个节点。
正确的代码应该是这样的:
~LinkedList(){//Destructor
cout << "Destructor called" << endl;
Node *curr = head, *next;
while (curr != nullptr){
next = curr->next;
delete curr;
curr = next;
}
}
可以简化为:
~LinkedList(){//Destructor
cout << "Destructor called" << endl;
while (head){
Node *next = head->next;
delete head;
head = next;
}
}
while (head != nullptr) {
Node* curr = head;
head = head->next;
delete curr;
}
制作它的主要原因是";复杂的";是while条件:它不应该在next
字段上,这可能是导致空指针的原因。
然后,在为下一个和删除进行指针杂耍的地方,有一些选择的自由。
我发现操纵头部会立即使目的变得非常明确。