链接的链接析构函数引发分段错误
Linked linked destructor raises segmentation fault
我正在尝试使用析构函数删除链表。
但是这段代码给出了一个分段错误:
~Node()
{
Node *current = this ;
Node *previous = NULL;
while(current != NULL)
{
previous = current;
current = current->next;
delete previous;
previous = NULL;
}
}
我做错了什么?
您不能删除当前节点本身,否则代码会调用未定义的行为。
你可以这样写
~Node()
{
delete next;
}
并且如果列表被定义为指向头节点的指针那么你需要写
delete head;
这里是演示程序
#include <iostream>
class Node
{
private:
int data;
Node *next;
public:
explicit Node( int data, Node *next = nullptr ) : data( data ), next( next )
{
}
~Node()
{
std::cout << "Deleting " << data << "...\n";
delete next;
}
};
void push_front( Node *&head, int data )
{
head = new Node( data, head );
}
int main()
{
Node *head = nullptr;
const int N = 10;
for (int i = 0; i < N; i++)
{
push_front( head, N - i );
}
delete head;
}
程序输出为
Deleting 1...
Deleting 2...
Deleting 3...
Deleting 4...
Deleting 5...
Deleting 6...
Deleting 7...
Deleting 8...
Deleting 9...
Deleting 10...
您应该从 delete
运算符中排除当前节点,因为代码已经是对 delete
的响应。再做一遍就像运行转圈一样。
所以将您的代码修改为:
~Node()
{
Node *current = this->next; // exclude current node
Node *previous;
while (current != NULL)
{
previous = current;
current = current->next;
previous->next = NULL; // avoid the delete below to propagate through list.
delete previous;
}
}
没有必要将 previous
设置为 NULL
,因为它会 运行 超出范围。但是需要将 previous
与其后继者分离,以避免析构函数再次跟随该链。
此代码假定 this
是列表的 first 节点,这将是执行 delete
的自然结果。如果出于某种原因您要在列表中间某处的节点上执行 delete
,目的是丢弃整个列表,那么您还需要对当前节点之前的节点重复上述循环.
我正在尝试使用析构函数删除链表。
但是这段代码给出了一个分段错误:
~Node()
{
Node *current = this ;
Node *previous = NULL;
while(current != NULL)
{
previous = current;
current = current->next;
delete previous;
previous = NULL;
}
}
我做错了什么?
您不能删除当前节点本身,否则代码会调用未定义的行为。
你可以这样写
~Node()
{
delete next;
}
并且如果列表被定义为指向头节点的指针那么你需要写
delete head;
这里是演示程序
#include <iostream>
class Node
{
private:
int data;
Node *next;
public:
explicit Node( int data, Node *next = nullptr ) : data( data ), next( next )
{
}
~Node()
{
std::cout << "Deleting " << data << "...\n";
delete next;
}
};
void push_front( Node *&head, int data )
{
head = new Node( data, head );
}
int main()
{
Node *head = nullptr;
const int N = 10;
for (int i = 0; i < N; i++)
{
push_front( head, N - i );
}
delete head;
}
程序输出为
Deleting 1...
Deleting 2...
Deleting 3...
Deleting 4...
Deleting 5...
Deleting 6...
Deleting 7...
Deleting 8...
Deleting 9...
Deleting 10...
您应该从 delete
运算符中排除当前节点,因为代码已经是对 delete
的响应。再做一遍就像运行转圈一样。
所以将您的代码修改为:
~Node()
{
Node *current = this->next; // exclude current node
Node *previous;
while (current != NULL)
{
previous = current;
current = current->next;
previous->next = NULL; // avoid the delete below to propagate through list.
delete previous;
}
}
没有必要将 previous
设置为 NULL
,因为它会 运行 超出范围。但是需要将 previous
与其后继者分离,以避免析构函数再次跟随该链。
此代码假定 this
是列表的 first 节点,这将是执行 delete
的自然结果。如果出于某种原因您要在列表中间某处的节点上执行 delete
,目的是丢弃整个列表,那么您还需要对当前节点之前的节点重复上述循环.