stl list item not removing

Im making a go fish card game and i have this function to remove a card from one deck and add it to another. I have it going through the list of the loser (the person who has to give away the card if they have it) If the card is not there then the function doesn't remove any cards but if the card is found then it infinite loops. first of all this for loop shouldn't loop infinitely right? And also this is how the .remove() works for stl lists?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void Hand::findItem( string item, list<string> win , list<string> lose)
{
	list<string>::iterator p;
    
    Card card;
    card.name = item;
    
    int i = 0;
    
    for (p = lose.begin(); p!=lose.end(); p++)
    {
        if (*p == item)
        {
            cout << " BLAH" << endl;
            
            lose.remove(item);
            win.push_back(item);
        }
    }
    printDeck();
} // end findItem 
After remove() pointer p will be invalidated and trying to increment it will lead to unexpecter results.

also remove() method deletes all entries of item.
If you want to delete one item, you should call erase() method and pass an iterator to element you want to delete: lose.erase(p). Note that p will still be invalidated.
I would use multiset for card storage however.
Last edited on
p points to an item. You remove that item. Where does p point now? Then the loop calls p++. Can p!=lose.end() still fail?

You have iterator, so you could use list::erase. Probably should.
not sure if 'win' and 'lose' need to pass by reference though. But you shouldn't remove elements in the list while iterating it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bool found = false;
for (p = lose.begin(); p!=lose.end(); p++)
{
    if (*p == item)
    {
        cout << "found" << endl;
        found = true;
        break;
    }
}
if (found)
{
    lose.remove(item);
    win.push_back(item);
}


or you may use std::find in <algorithm> and list::erase to remove only one element equal to 'item' (list::remove removes from the container all the elements that compare equal to 'item'

1
2
3
4
5
6
list<string>::iterator p = find(lose.begin(), lose.end(), item); 
if (p != lose.end())  //if p == lose.end() then 'item' is not found
{
    lose.erase(p);
    win.push_back(item);
}
Last edited on
To move an element from one list to another you can use the splice function.
win.splice(win.end(), lose, p);
And note that you cannot continue iteration after this, because you will continue iterate over win array!

Just tell me: can there be duplicate elements in your list?
Topic archived. No new replies allowed.