free():在 tcache 2 中检测到双重释放,在链表中删除 c++ 中的节点以及析构函数在此代码中的工作方式
free(): double free detected in tcache 2, in linked List deletion of a node in c++ and how destructor is working in this code
class Node{
public:
int data;
Node* next;
Node(int d){
data = d;
next = NULL;
}
~Node(){
delete next;
}
};
class List{
public:
Node* head;
Node* tail;
List(){
head = NULL;
tail = NULL;
}
~List(){
delete head;
}
void push_back(int data){
Node* n = new Node(data);
if(head == NULL){
head = tail = n;
}else{
tail->next = n;
tail = n;
}
}
void print(){
Node* temp = head;
while(temp != NULL){
cout<<temp->data<<" ";
temp = temp->next;
}
}
void deleteNode(int d){
Node* curr = head;
Node* prev = NULL;
while(curr != NULL){
if(curr->data == d){
if(prev == NULL){
head = head->next;
delete curr;
break;
}else{
prev->next = curr->next;
curr->next = NULL;
delete curr;
break;
}
}
prev = curr;
curr = curr->next;
}
}
};
int main(){
List l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.push_back(4);
l.push_back(5);
l.deleteNode(1);
l.print();
}
如果我从1->2->3->4->5中删除1
预期输出:2->3->4->5
输出:free():在 tcache 2 中检测到双重释放;
原因:节点Class中的析构函数。如果我删除它工作正常。
疑问 : 如果我在节点class中删除析构函数在节点class 那我怎样才能释放内存。还有谁能解释一下 析构函数在 Node 和 List 中是如何工作的 class.
有人可以帮我解决这个问题,或者可以提供替代解决方案。
谢谢!!!
~Node(){ delete next; }
使得很难从该列表中删除单个节点。它也会删除它之后的 所有 个节点。
我建议 Node
个人不要 delete
关注 Node
:
class Node {
public:
int data;
Node* next;
Node(int d) : // colon starts the member initializer list
data(d), next(nullptr)
{
// the body of the constructor can now be empty
}
// No user-defined destructor needed here
};
相反,delete
List
的析构函数中的所有 Node
:
~List() {
for(Node* next; head; head = next) {
next = head->next;
delete head;
}
}
与手头的问题无关。这些只是建议:
您可以使 Node
的构造函数更通用一些,这样就可以在构造时提供下一个 Node
:
class Node {
public:
int data;
Node* next;
// `nullptr` below is a default argument that will be used if the
// user of this class does not provide a second argument
Node(int d, Node* n = nullptr) :
data(d), next(n)
{}
};
这可以在名为 push_front
的 List
成员函数中使用:
void push_front(int data) {
head = new Node(data, head);
if(!tail) tail = head;
}
与此无关,您 可以 使 push_back
更清晰一点,甚至根本不改变当前的 Node
:
void push_back(int data) {
Node* n = new Node(data);
if(tail) tail->next = n;
else head = n;
tail = n;
}
为了跟进我的评论:扔掉你的 Node
和 List
class,并实际使用语言:
#include <forward_list>
#include <iostream>
int main(){
std::forward_list< int > l { 1, 2, 3, 4, 5 };
l.remove( 1 );
for ( auto & node : l )
{
std::cout << node << " ";
}
}
class Node{
public:
int data;
Node* next;
Node(int d){
data = d;
next = NULL;
}
~Node(){
delete next;
}
};
class List{
public:
Node* head;
Node* tail;
List(){
head = NULL;
tail = NULL;
}
~List(){
delete head;
}
void push_back(int data){
Node* n = new Node(data);
if(head == NULL){
head = tail = n;
}else{
tail->next = n;
tail = n;
}
}
void print(){
Node* temp = head;
while(temp != NULL){
cout<<temp->data<<" ";
temp = temp->next;
}
}
void deleteNode(int d){
Node* curr = head;
Node* prev = NULL;
while(curr != NULL){
if(curr->data == d){
if(prev == NULL){
head = head->next;
delete curr;
break;
}else{
prev->next = curr->next;
curr->next = NULL;
delete curr;
break;
}
}
prev = curr;
curr = curr->next;
}
}
};
int main(){
List l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.push_back(4);
l.push_back(5);
l.deleteNode(1);
l.print();
}
如果我从1->2->3->4->5中删除1
预期输出:2->3->4->5
输出:free():在 tcache 2 中检测到双重释放;
原因:节点Class中的析构函数。如果我删除它工作正常。
疑问 : 如果我在节点class中删除析构函数在节点class 那我怎样才能释放内存。还有谁能解释一下 析构函数在 Node 和 List 中是如何工作的 class.
有人可以帮我解决这个问题,或者可以提供替代解决方案。
谢谢!!!
~Node(){ delete next; }
使得很难从该列表中删除单个节点。它也会删除它之后的 所有 个节点。
我建议 Node
个人不要 delete
关注 Node
:
class Node {
public:
int data;
Node* next;
Node(int d) : // colon starts the member initializer list
data(d), next(nullptr)
{
// the body of the constructor can now be empty
}
// No user-defined destructor needed here
};
相反,delete
List
的析构函数中的所有 Node
:
~List() {
for(Node* next; head; head = next) {
next = head->next;
delete head;
}
}
与手头的问题无关。这些只是建议:
您可以使 Node
的构造函数更通用一些,这样就可以在构造时提供下一个 Node
:
class Node {
public:
int data;
Node* next;
// `nullptr` below is a default argument that will be used if the
// user of this class does not provide a second argument
Node(int d, Node* n = nullptr) :
data(d), next(n)
{}
};
这可以在名为 push_front
的 List
成员函数中使用:
void push_front(int data) {
head = new Node(data, head);
if(!tail) tail = head;
}
与此无关,您 可以 使 push_back
更清晰一点,甚至根本不改变当前的 Node
:
void push_back(int data) {
Node* n = new Node(data);
if(tail) tail->next = n;
else head = n;
tail = n;
}
为了跟进我的评论:扔掉你的 Node
和 List
class,并实际使用语言:
#include <forward_list>
#include <iostream>
int main(){
std::forward_list< int > l { 1, 2, 3, 4, 5 };
l.remove( 1 );
for ( auto & node : l )
{
std::cout << node << " ";
}
}