0

I have an Animals class, and from this specific animals are derived. I have a list of animals called mItems. I want to see if my lions are hungry. I have created virtual functions in my Animals class:

    virtual void IsLion() {return false;}
    virtual void IsHungry() {return false;}
    virtual void SetHungry(bool state) {}

In my Lion class I have extended these:

    virtual void IsLion () {return true;}
    virtual void IsHungry () {return mHungry;}
    virtual void SetHungry () {mHungry = state;}

mHungry is a boolean member variable that will represent whether or not the lion is hungry.

void CSafari::KillHungryLion()
{
for(list<CAnimals *>::iterator i=mItems.begin(); 
        i != mAnimals.end();  i++) 
    {
        if((*i)->IsLion())
        {
            if((*i)->IsHungry())
            {
              mItems.remove(*i);
              delete *i;
            }

         }
    }
 }

mItems is a list of pointers to CAnimal objects.

If a Lion is hungry, he is dead! The problem I am having is endless segfaults. I cannot pinpoint where I am going wrong. I have a function that is essentially equivalent to this that periodically updates the lions to being hungry, then I call this. It appears that it segfaults when I try to remove the items from mItems. Any ideas?

Zaffy
  • 16,801
  • 8
  • 50
  • 77
jonnywalkerr
  • 157
  • 8

1 Answers1

2

Once you remove the item from the list, the iterator pointing to that item is invalid. See https://stackoverflow.com/a/3329962/1558890 . Calling i++ (or ++i) on an invalid iterator is likely to lead to a segfault.

Community
  • 1
  • 1
Jim Garrison
  • 4,199
  • 4
  • 25
  • 39
  • 1
    Might be helpful to mention that he can use the return value of list::erase to keep his iterator valid, or break and make the function only delete the first hungry lion. – Dan O Sep 29 '13 at 03:54