使用递归函数删除链表
delete linked list using recursive function?
struct Node {
int value;
Node* next;
~Node() {
delete next;
}
};
Node* deleteList(Node* p) {
if(p == nullptr) return nullptr;
Node* pNext = p->next;
delete p;
return deleteList(pNext);
}
编译器说了一些关于访问错误的事情。我尝试设置断点来调试它。如果链表是 [3, 2, 1],它首先删除 3,然后删除 2 和 1,然后跳回到 2,然后遇到异常。有人可以告诉我问题出在哪里吗?
节点结构的析构函数已经在"next"上调用了 delete。因此,它转到"next"并调用其析构函数,依此类推。然后,链表中跟随p
的所有节点都将通过调用delete p;
删除(其中 p 是节点*(。
我建议你去掉节点的析构函数,以防止这种链破坏发生。
struct Node {
int value;
Node* next;
};
作为旁注,虽然我不知道你的代码的其余部分,但我看不出为什么 deleteList(Node* p( 应该返回一个 Node*(因为它将始终是 nullptr,没有返回有趣的结果(。
void deleteList(Node* p)
{
if(p == nullptr) return;
Node* pNext = p->next;
delete p;
deleteList(pNext);
}
如果链表是: [3, 2, 1]
,当您调用 deleteList
时,会发生以下情况:
-
p = 3
pNext = 2
,3
被delete p;
删除 然后调用析构函数,因此delete next
将删除2
并以递归方式1
。 -
然后在
deleteList
函数中delete p
后,再次调用deleteList(pNext)
,所以这次:p = 2
,pNext = 1
,由于2
在上一步中已经被删除,因此当您再次调用delete p
时它会损坏。
因此,请删除~Node()
中的delete next;
。
实际上,我不明白为什么要使用deleteList
,因为它总是会返回nullptr
并删除所有节点。那么为什么不删除deleteList
功能,并将delete next;
保持在~Node()
中。您可以直接删除已创建的Node
对象。
当然,完成此任务的最佳方法是: std::list
.
我敢打赌,您正在delete
已被删除的实例上多次调用。当你调用delete p;
时,p
的析构函数将被调用,并且它正在删除列表中的下一个节点。然后递归调用deleteList
,将刚刚被p
的析构函数删除的节点传递给它,使你持有的指针无效。
您需要做的是确定Node
是否拥有列表中它后面的Node
(即,它是否负责清理它(,或者是否会由一些外部代码来处理这个问题。你不能两者兼而有之。
编辑:
顺便说一句,你真正想要的不是递归删除函数,而是deleteList
函数中的一个循环。像...
struct Node {
int value;
Node* next;
};
// Loop in the function; recursion not required, and no return value.
void delete_list(Node* n)
{
Node* tmp;
while (nullptr != n) {
tmp = n->next;
delete n;
n = tmp;
}
}
在这种情况下,Node
实例不拥有其同级Node
(Node.next(,也不负责解除分配它;这取决于delete_list
函数。
从 Node
的析构函数中删除行delete next;
。
我认为您可能有两种选择。首先,正如 R Sahu 所说,删除析构函数中的delete next
。
struct Node {
int value;
Node* next;
};
Node* deleteList(Node* p) {
if(p == nullptr) return nullptr;
Node* pNext = p->next;
delete p;
return deleteList(pNext);
}
其次,只需删除 deleteList
中链接的头节点,但不递归删除节点。
struct Node {
int value;
Node* next;
Node() : value(0), next(nullptr)
{}
~Node() {
if (next != nullptr)
{
delete next;
}
}
};
Node* deleteList(Node* p) {
if (p != nullptr)
{
delete p;
}
return nullptr; // in fact your code always return nullptr. so it just return nullptr here.
}
- 我们可以删除链表中静态内存中的节点吗
- 为什么我的双向链表删除函数会删除多个节点?
- C++ 从链表中删除给定整数的倍数
- 链表删除功能的单指针 // 是可能的
- C++链表删除和删除返回功能
- 基于给定字符串数据类型的链表删除节点
- C++循环链表删除,计数从下一个节点开始
- C++ 链表删除了错误的项目
- 不太清楚为什么我的递归链表删除函数有效?我很想解释一下
- 双向链表删除C++中的偶数
- 双链表删除节点与索引C++
- 双链表C++删除元素
- C++链表删除节点
- 在双重链表删除函数中出现Seg错误
- 链表删除最后一个节点c++
- 链表删除和复制
- 链表:删除带有选定数据的节点
- 链表(删除节点)
- 双链表:删除c++节点
- 运行时链表删除函数出错