Reputation: 1
Im trying to create function to delete from single-linked list all elements with value smaller as next (following) element value. For some reason programm throws "free():double free detected in tcache 2". What is wrong with my function ? list is not empty.
#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);
Upvotes: -2
Views: 146
Reputation: 597941
There are a number of problems with your code.
next = list->next;
is undefined behavior if the list is empty (ie list
is null).
prev->next=next;
is undefined behavior for the 1st node in the list, as prev
is unassigned.
You are not updating curr
after delete
'ing the node it points at, which is also undefined behavior.
The list
pointer is being passed in by value, so the caller's pointer can't be updated if the 1st node in the list is freed, thue the caller will be left with a dangling pointer to invalid memory.
Try this instead:
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;
}
}
UPDATE: In comments, you changed your requirements to need the list scanned in multiple iterations. The code above works fine for 1 iteration, so you could simply call it multiple times in a loop until there are no more removals performed, eg:
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));
...
Upvotes: 1