提问人:Arsenyev01 提问时间:11/16/2022 最后编辑:Remy LebeauArsenyev01 更新时间:11/16/2022 访问量:53
为什么在使用单链表时在 tcache 2 中检测到 programm 抛出双重释放 [已关闭]
Why does programm throws double free detected in tcache 2 while using single linked list [closed]
问:
我试图创建函数以从单链表中删除所有值小于下一个(以下)元素值的元素。出于某种原因,programm 抛出“free():d ouble free detected in tcache 2”。我的功能有什么问题? list 不为空。
#include <iostream>
using namespace std;
struct Elem
{
int num;
Elem* next;
};
void deleteFromLinkedList(Elem* list) {
Elem* curr, * next, *prev;
curr = list;
next = list->next;
while (next != NULL)
{
if (curr->num < next->num) {
prev->next=next;
delete curr;
curr = prev;
continue;
}
prev = curr;
curr = next;
next = curr->next;
};
}
int main()
{
Elem* first = NULL, * last = NULL, * p;
int i;
cout << "Enter any number or 0 to finish: ";
cin >> i;
while (i != 0)
{
p = new Elem;
p->num = i;
p->next = NULL;
if (first == NULL)
{
first = last = p;
}
else
{
last->next = p;
last = last->next;
};
cout << "Enter any number or 0 to finish: ";
cin >> i;
};
deleteFromLinkedList(first);
答:
1赞
Remy Lebeau
11/16/2022
#1
您的代码存在许多问题。
next = list->next;
如果列表为空(即为 null),则为未定义的行为。list
prev->next=next;
是列表中第一个节点的未定义行为,因为未分配。prev
在它指向的节点之后,您不会更新,这也是未定义的行为。curr
delete
指针是按值传入的,因此如果列表中的第一个节点被释放,则调用方的指针无法更新,因此调用方将留下一个指向无效内存的悬空指针。list
请尝试以下操作:
void deleteFromLinkedList(Elem* &list) {
if (!list)
return;
Elem *curr = list, *next = list->next, *prev = NULL;
while (next)
{
if (curr->num < next->num) {
if (prev)
prev->next = next;
else
list = next;
delete curr;
}
else {
prev = curr;
}
curr = next;
next = curr->next;
}
}
更新:在注释中,您更改了要求,要求在多次迭代中扫描列表。上面的代码适用于 1 次迭代,因此您可以简单地在一个循环中多次调用它,直到不再执行删除,例如:
bool deleteFromLinkedList(Elem* &list) {
if (!list)
return false;
Elem *curr = list, *next = list->next, *prev = NULL;
bool anyRemoved = false;
while (next)
{
if (curr->num < next->num) {
if (prev)
prev->next = next;
else
list = next;
delete curr;
anyRemoved = true;
}
else {
prev = curr;
}
curr = next;
next = curr->next;
}
return anyRemoved;
}
...
while (deleteFromLinkedList(first));
...
评论
0赞
Arsenyev01
11/16/2022
是的,但这只会删除一个元素。-1 我试图创建函数以从单链表中删除所有值较小的元素。所以 9,8,7,12,11,6 将是 12,11,6
0赞
user4581301
11/16/2022
@Arsenyev01 如果有一个删除一个节点的函数,则可以为每个需要删除的节点调用它。但要注意画家施莱米尔。
0赞
Remy Lebeau
11/16/2022
@Arsenyev01 您最初提供的示例应该产生,而我提供的代码完全正确地做到了这一点,我提供的演示证明了这一点。我刚才尝试了你的新示例,但输出不是.为什么会产生不小于?您似乎希望被删除,因为它们都小于 .在我发布我的答案后,您显然已经改变了您的要求。请不要那样做...15,12,11,7,9,5,2,3
15,12,11,9,5,3
9,8,7,12,11,6
9,8,12,11,6
12,11,6
9,8,7,12,11,6
12,11,6
9
8
9,8,7
12
0赞
Remy Lebeau
11/16/2022
@Arsenyev01 如果您的需求发生了变化,请接受原来的问题,并针对新需求发布一个新问题(当然,在您尝试了基于您从该答案中学到的解决方案之后)。
1赞
Remy Lebeau
11/16/2022
@Arsenyev01你之前没有说过需要多次迭代。同样,你在事后不断改变需求,那么你怎么指望任何人给你一个准确的答案呢?为了将来参考,请在提出新问题时提前发布所有相关详细信息。无论如何,我已经给你的代码在 1 次迭代中工作正常,所以你可以简单地在循环中调用它,直到不再执行删除(工作演示)。我已经更新了我的答案以显示这一点。
评论
void deleteFromLinkedList(Elem* list) {
问题 #1 是按值而不是通过引用传递指向头节点的指针。这意味着即使正确实现了 deleteFromLinkedList(),您也永远无法更新指向 head 的指针。node