6
\$\begingroup\$

I tried doing this but it cause an access violation.

void GameObjectFactory::Update()
{
     for( std::list<GameObject*>::iterator it=gameObjectList.begin() .....
          (*it)->Update();
}

void Bomb::Update()
{
     if( time == 2.0f )
     {
         gameObjectFactory->Remove( this );
     }
}

void GameObjectFactory::Remove( ... )
{
     gameObjectList.remove( ... );
}

My thoughts would be to mark the object to be dead then let the factory handle it the on next frame for deletion. Is it the best and fastest way? What do you think?

\$\endgroup\$
7
  • \$\begingroup\$ How do you iterate through the object collection? Do you by any chance use a for i = 0; i < length; i++ type loop? Could removing an object affect the collection structure? \$\endgroup\$
    – AturSams
    Oct 6, 2012 at 16:36
  • \$\begingroup\$ How do you store your objects? A vector of pointers or a vector of actual objects? How do you delete them? Also, I don't know what you think an ObjectFactory is, but I'm pretty sure it's not there to actually update your objects. \$\endgroup\$
    – jcora
    Oct 6, 2012 at 16:39
  • \$\begingroup\$ Whatever you do, you don't want to iterate over all your objects looking for ones marked dead. You could store a seperate std::vector or std::list of objects to be deleted which some sort of object manager could process. \$\endgroup\$
    – derivative
    Oct 6, 2012 at 16:46
  • \$\begingroup\$ I'm storing it using std::list<GameObject*>; On my GameObjectFactory, I loop through all the objects using the iterator of the std::list. It just call the Update function. Now for the removing the object. I just call Remove() if the time == 2.0f. Now that caused an access violation because of the loop from the GameObjectFactory. Most likely, the iterator is not pointing to anything. Hope you get what I'm saying. Thank you. \$\endgroup\$
    – Balls
    Oct 6, 2012 at 16:48
  • \$\begingroup\$ Is it possible you are changing the list while you are still iterating over the list? \$\endgroup\$
    – AturSams
    Oct 6, 2012 at 17:08

3 Answers 3

8
\$\begingroup\$

My thoughts would be to mark the object to be dead then let the factory handle it the on next frame for deletion. Is it the best and fastest way? What do you think?

Why wait until the next frame? Just remove it at the end of the current frame. But I wouldn't worry about it being the "fastest" way, unless you're dealing with lots of dead objects every frame. If you are, you should be using an object pool.

But yes, a flag or putting a reference to it in a separate list, whatever. Shouldn't matter. Implementing one or the other should be trivial to do and if you really care you can put some performance benchmarks on it and really get the only definitive answer to your question.

\$\endgroup\$
2
\$\begingroup\$

How about using std::remove_if?

bool shouldBeRemoved (GameObject* val) { return (val->time >= 2); }
std::remove_if(gameObjectList.begin(), gameObjectList.end(), shouldBeRemoved);
\$\endgroup\$
0
\$\begingroup\$

I think it is possible you are changing the list while you are still iterating over the list.

To avoid this, instead of deleting the unused (dead) objects. Create a new helper list and add the live objects to that new helper list, when the loop is over, remove the old list from memory and have it's pointer point to the helper list. This could help avoid any bugs that occur because you are iterating over and modifying a list in the time.

  1. Create new helper list
  2. Add each 'live' object to that new list as you iterate over it.
  3. kill the old list
  4. Have the old list's pointer, point to the new list.
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .