Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

list.remove_if() crashing the program

I’m working on a game and I’m trying to add collectables. I’m trying to remove the object from the list after the player has collided with it, but it ends up crashing and says:

Unhandled exception thrown: read access violation.
__that was 0xDDDDDDE9.

It says this on the for loop statement, but I think it has to do with the remove_if() function.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Here is my code:

for (sf::RectangleShape rect : world1.level1.brainFrag) {
        
        collides = milo.sprite.getGlobalBounds().intersects(rect.getGlobalBounds());
        
        if (collides == true) {
            world1.level1.brainFrag.remove_if([rect](const sf::RectangleShape val) {
                if (rect.getPosition() == val.getPosition()) {
                    return true;
                }
                else {
                    return false ;
                }
            });
            
            brainFrag -= 1;
            collides = false;
        }
        
    }
    if (brainFrag == 0) {
        milo.x = oldPos.x;
        milo.y = oldPos.y;
        brainFrag = -1;
    }

>Solution :

I don’t understand your approach, you loop the rects, then when you find the one you want to remove, you search for it again through list<T>::remove_if.

I think that you forgot about the fact that you can use iterators in addition to a range-based loop:

for (auto it = brainFrag.begin(); it != brainFrag.end(); /* do nothing */)
{
  bool collides = ...;

  if (collides)
    it = world1.level1.brainFrag.erase(it);
  else
    ++it;
}

This allows you to remove the elements while iterating the collection because erase will take care of returning a valid iterator to the element next to the one you removed.

Or even better you could move everything up directly:

brainFrag.remove_if([&milo] (const auto& rect) {
 return milo.sprite.getGlobalBounds().intersects(rect.getGlobalBounds())
}

A side note: there’s no need to use an if statement to return a boolean condition, so you don’t need

if (a.getPosition() == b.getPosition()
  return true;
else
  return false;

You can simply

return a.getPosition() == b.getPosition();
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading