As a general C++ advice, I would use std::list instead of a DIY list implementation, but since I wrote quite some list logic myself in the old C-days, I'll give it a go.
There are 2 essential problems with your code.
First of all, whenever removing an element from a single-linked list, you should set the next pointer of the previous element to the next of the deleted one. You can do something like this:
Node *previousNode = …;
while(pPtr != nullptr)
{
Node *nextNode = pPtr->next;
if (pPtr->ShouldDelete())
{
delete pPtr;
previousNode->next = nextNode;
}
else
{
previousNode = pPtr;
}
pPtr = nextNode;
}
Notice that no specific if-tests within the for-loop on nullptr
are needed. You should tell the previous node that it now points to the next of the deleted one. If there is no next one, the previous->next
will just point to a nullptr, indicating the end of the list.
The second problem is that you don't have any clear 'start of the list'. In my example code above, it becomes quite hard to indicate what the previousNode
is. Is it a nullptr
? But what if we remove the first element?
You could easily add logic here to indicate keep track of the first element, initialize previousNode
to nullptr, and if the first is deleted, just don't set previousNode->next' and keep previousNode equal to
nullptr` in that case, but what about the caller? How can the caller know that the first element has been deleted and the list now starts later.
My preferred solution is to have a separate List
struct/class, and keep the start of the list (the first Node) as a member in the List
struct/class. Instead of passing the startNode to the function, you should pass the List
instance.
The code in the while-loop now becomes a bit longer, since you need to adapt previousNode->next=nextNode
to this:
if (previousNode)
previousNode->next = nextNode;
else
list->firstNode = nextNode;
If you don't want to introduce a new List
struct/class, you could also return the new firstNode
as return value from your function, like this:
if (previousNode)
previousNode->next = nextNode;
else
startNode = nextNode;
…
return startNode;
Notice that this second approach only works if the caller if the function is also the one maintaining the list, and there are no other places pointing to the startNode.
In any case, if multithreading is involved, you probably want a decent List
class with a kind of mutex
(ideally std::list
decorated with a mutex
).