Skip to main content
GameDev.net gamedev.net
🔒 Locked

Game freezes when deleting/erasing with a deque of pointers/shared_ptrs

Started by The Fat Controller Nov 5, 2010 at 1:26 AM 2 replies 1k views
Original Post
The Fat Controller
The Fat Controller

Hi everyone, I've been working on a 2D shooter for fun and to improve my C++, but I've got to a part where I'm struggling.

Whenever a bullet goes offscreen or hits an enemy the game freezes with processor usage at 100%. Here's my code for managing sets of bullets, it's where things seem to be going wrong:

void unitHandler::bullets(deque<boost::shared_ptr<Bullet> >& bulletPool){    for(deque<boost::shared_ptr <Bullet> >::iterator iter = bulletPool.begin(); iter != bulletPool.end(); /*nothing*/) //iterate over the deque of bullets    {        if((*iter)->isFired == true) //if the bullet is flying        {            (*iter)->move(); //move the bullet            (*iter)->show(); //and show it            iter++; //increment the iterator        }        else //otherwise the bullet is offscreen or whatever, needs removing        {            iter = bulletPool.erase(iter);        }    }}


I've also tried using regular pointers, but found the same thing happened:

void unitHandler::bullets(deque<Bullet*>& bulletPool){   deque<Bullet*>::iterator iter;     for(iter = bulletPool.begin(); iter != bulletPool.end(); /* */ )     {        if((*iter)->isFired == false)        {            delete *iter; //delete the bullet object currently pointed to            iter = bulletPool.erase(iter);        }        else        {            (*iter)->move();            (*iter)->show();            iter++;        }    } }


If I take the delete line out then it doesn't freeze, but that way only the pointers to the bullets get freed, not the bullet objects, and that's bad of course.

Thanks in advance to anyone who has read this far, I'd appreciate your help. I'm hoping I'm just overlooking something obvious.

Do not mark threads 'solved' -- jpetrie

[Edited by - jpetrie on November 5, 2010 1:01:30 PM]
Katie
Katie
Before launching off on other things, deque has O(N) insertion/deletion performance. It's not a good container to use for this purpose, exactly because you want to be able to delete things out of the middle. I'd suggest trying list which is O(1) for those operations.


Mind you, "freezing" still seems a bit of a performance hit. How big is your N likely to be? Even 100s or 1000s ought not to noticeably hang the CPU.

As another test, every frame, create and delete a bullet using a smart pointer you store somewhere else. If you still get the hanging from this test, your bullet store isn't the problem, it's your bullet class.

The Fat Controller
The Fat Controller
Good point, I'll switch to lists after I've gotten this ironed out.

Unfortunately the freezing isn't slowdown, the tests I did below run at a good framerate. They aren't crashing the game and memory usage looks stable, whereas it rockets up if I omit the delete line in the first case, or the erase line in the second.

Regular pointers:

for(int i = 0; i < 10000; i++) //build a deque with 10000 pointers to separate bullet objects   {       Bullet* bulletPtr = new Bullet(30, 30, 10);       bulletdeque.push_back(bulletPtr);   }for(int i = 0; i < 10000; i++) //destroy the contents of the deque   {       delete bulletdeque[0];       bulletdeque.erase(bulletdeque.begin());   }


Smart pointers:

for(int i = 0; i < 10000; i++)   {       boost::shared_ptr<Bullet> bulletPtr(new Bullet(20, 20, 10));       smartptrbulletdeque.push_back(bulletPtr);   }for(int i = 0; i < 10000; i++)   {       smartptrbulletdeque.erase(smartptrbulletdeque.begin());   }


Here are the show and move methods for my bullet if they help:

void Bullet::move(){    if(isFired)    {        x += xVel;        y += yVel;    }    if ((x < -width)||(x > WORLD_WIDTH + width)||(y < -height)||(y > WORLD_HEIGHT))    {        isFired = false;    }}void Bullet::show(){    if(isFired)    {        tex.draw(textures[texIDs[0]], x, y, width, height);    }}
The Fat Controller
The Fat Controller
Quote:
Original post by Katie
If you still get the hanging from this test, your bullet store isn't the problem, it's your bullet class.


Ah, this is right!!

My last couple of tests were only successful because I hadn't assigned textures to the bullets. If I do that then delete always fails.

The bullet objects don't contain actual textures though, they each have a deque of GLuints that correspond to particular textures...

I'll have a go at working out what's going on and post code when I get frustrated :)

EDIT: It's fixed. My GameUnit class, which Bullet is descended from, had a destructor that I'd partially commented out, which led to an infinite loop inside it, hence the game freezing whenever a bullet was deleted...

Thanks Katie, I probably would've spent hours more agonizing over the stuff in my first post if it wasn't for your comments.

[Edited by - The Fat Controller on November 5, 2010 8:44:06 AM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.