views:

54

answers:

2

Note that the order can go either way (erase first then push back, just that this way doesn't require creating a local reference to the object).

  for ( GameObjItr gameObj = m_gameObjects.begin();
        gameObj != m_gameObjects.end(); gameObj++ ) {
    if ( *gameObj && *gameObj != gameObject ) {
      const sf::FloatRect &otherObj = ( *gameObj )->GetCollisionBox();
      if( mainObj.Intersects( otherObj ) ) {
        m_gameObjects.splice( m_gameObjects.end(), m_gameObjects, gameObj );
        return m_gameObjects.back();
      }
    }
  }

  return NULL;
}

The idea is that if the function finds an object colliding with the object passed, it adds that object to the end of the list, erases it from its current position, then returns the object. I don't think iterator invalidation is a problem since I am returning immediately after the erasure?

The code causes the program to crash.

P.S. cppreference says that erase "deletes" the object, but I assumed that this just removed it from the list. (If this is wrong, how can I remove an element by its location. The remove function doc I'm reading only allows passing the value of the object).

Edit: The location of the crash isn't always the same, but it occurs because of this code (i.e. if I revert it, acts normally). What causes a variably timed delayed crash? I do not want the object found to be destroyed.

GameObject* GameObjectManager::DetectCollision( const GameObject *
  gameObject ) {
  const sf::FloatRect &mainObj = gameObject->GetCollisionBox();

  for ( GameObjItr gameObj = m_gameObjects.begin();
        gameObj != m_gameObjects.end(); gameObj++ ) {
    if ( *gameObj && *gameObj != gameObject ) {
      const sf::FloatRect &otherObj = ( *gameObj )->GetCollisionBox();
      if( mainObj.Intersects( otherObj ) ) {
        m_gameObjects.splice( m_gameObjects.end(), m_gameObjects, gameObj ); //<--------
        return m_gameObjects.back(); //<-------------
      }
    }
  }

  return NULL;
}

Edit Found the bug, when moving the object to the end of the list, caused infinite loop between 2 GameObjects colliding. Sorry, couldn't have been deciphered from code posted.

A: 

When you say:

m_gameObjects.erase( gameObj );

the destructor for the thing contained in the list being erased (if it has one) will be called. It's not clear from your question what the type of this thing is, or if this destructor call is expected.

anon
Thanks. Still crashes when I use splice though...will edit. I'll post the whole function. Destructor call not expected.
person
A: 

"m_gameObjects.splice( m_gameObjects.end(), m_gameObjects, gameObj );"
Do you want to move the gameObj to the last position in the list? That is what the above line suggests. If yes, then
if the gameObj == m_gameObjects.end() or ++gameObj == m_gameObjects.end()
it is a NULL operation.

One more thing, you are doing a post-increment on the iterator in the for loop make it pre-increment. This has nothing to do with the crash though.

Jagannath