• Advertisement

Archived

This topic is now archived and is closed to further replies.

pointers sharing dymanic memory

This topic is 5060 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

high, im working on a 2d RPG w/ c++ and OpenGL. i have an updating "engine", which will update each of my objects. i have a class called World_Update, which contains a virtual bool Update(). most of my classes inherit from World_Update. then, World_Update has a static member which is list''s of World_Update*. my world_update class also has a static member Register(World_Update*); which will register an object into the updating engine. heres the problem : I have a global list of Enemy* called list < Enemy* > world_enemies. this is a list of any enemies that are in the world. my player class has a member which is a vector < Enemy*>. this is basically just a list of any enemies that are on the screen that he can target. when the player goes to target, i will loop through EVERY enemy in the world_enemies list, call On_Screen(), and if the enemy is on the screen, he will be placed in the vector of Enemy*. ok, so now all i have to do is register any enemies i make with the updating engine, AND the world list of enemies. i do this while reading in a map: if( there is an enemy here) { Enemy *e = new Enemy(); World_Update::Register(e); world_enemies.push_back(e); } OK - now is where i should tell you about the updating engine. you see,i do something like this : (for each object in my world update list) { if( ! itor->Update()) { delete *itor; itor = world_update.erase(itor); } } basically, an object is removed from the world when his Update() returns false. this could be when an enemy dies, when a particle''s life ends, whatever. the problem is - what happends when an enemy dies? he is removed from the world_update list, BUT his address is still sitting in the world_enemy list!!! this pointer is now garbage but its kept in my world_enemy list and i have no way of telling if its in-valid. im just looking for suggestions on how to handle this. if you suggest auto ptrs or a boost one, could you please give an example on how they are used? thanks for any help!!!

Share this post


Link to post
Share on other sites
Advertisement
yes, either use a smart pointer or implement a message broadcast system. when any unit dies it sends a broadcast message that goes to basically every object in the game that's been registered as a listener to the broadcast system. when the player gets this message he will "care" about it and just remove the pointer from his list.

the alternative is to redesign your engine so that people don't hold pointers but rather they hold objectIDs (int) of the enemy objects. you hold all objects in one global list and implement a method of storing them, like a hashmap, that is quickly acessable. it will introduce a little bit of overhead and latency but it will save you lots of debugging headaches.

-me

[edited by - Palidine on June 9, 2004 9:45:50 PM]

Share this post


Link to post
Share on other sites
some ideas:

- Don''t store a list of enemies to track.

- Flag any update object with some kind of "don''t kill me" message so the engine doesn''t delete him, just erase.

- switch to using handles or ID as Palidine suggest. Give each object an ID stamp and then when you want a pointer to that enemy, you call

Enemy* SomeGlobalReserve::GetEnemyByID( int ID );

which returns NULL if there is no enemy with that ID (he''s dead, Jim). I''ve used that trick before. THe problem is that you have to reacquire the pointer everytime you want to use it which is bad for an action game :-( but great for a one-time lookup :-)

- and of course the auto_ptr, but i''ve never actually used one before. It would be good if you are putting pointers to dynamic memory in many object''s hands.

Share this post


Link to post
Share on other sites
quote:
Original post by leiavoia
some ideas:

- Don''t store a list of enemies to track.



then how do i retrive the enemies in the world, and find out if they are on screen for the player''s targetting?

quote:

- Flag any update object with some kind of "don''t kill me" message so the engine doesn''t delete him, just erase.



yes, but then i have a bunch of pointers laying around in space? if not, who deletes it?

quote:

- switch to using handles or ID as Palidine suggest. Give each object an ID stamp and then when you want a pointer to that enemy, you call

Enemy* SomeGlobalReserve::GetEnemyByID( int ID );

which returns NULL if there is no enemy with that ID (he''s dead, Jim). I''ve used that trick before. THe problem is that you have to reacquire the pointer everytime you want to use it which is bad for an action game :-( but great for a one-time lookup :-)



im trying to envision this sytem in my head... gotta think about it for a minute

quote:

- and of course the auto_ptr, but i''ve never actually used one before. It would be good if you are putting pointers to dynamic memory in many object''s hands.


i think ill just wind up looking into a boost::shared_ptr then...

thanks for anymore suggestions!!!

Share this post


Link to post
Share on other sites
Memory management is a tricky subject. I have Game Programming Gems and it discusses a couple different approachs to this. Handles and auto-pointers are good ideas. Maybe you could revise you World list so it maintains several lists; such as an EnemyList, PowerUpList and so on.
--L2S

Share this post


Link to post
Share on other sites
quote:
yes, but then i have a bunch of pointers laying around in space? if not, who deletes it?


Somebody else, obviously :-) You can have lots of pointers out there, just don''t have lots of people trying to delete them. Of course, even that''s not very safe, but you''re pretty much the only person working on it i''m sure, so i wouldn''t worry TOO much about that.

You might try accessing specific class objects (Enemy) via a class''s insternal list of objects.

Share this post


Link to post
Share on other sites
hmm... so maybe ill make a static::list of Enemy*, then in the enemy constructor i would push back ''this'' into the list, and in the destructor i would erase it from the list (but not delete it of course).... thanks for the help

Share this post


Link to post
Share on other sites
ok, im really new to copy constructors and ive never had to find something to erase it.. so i just want to make sure im implementing this right. first, the Enemy class gets a member

static list < Enemy* > enemies_in_world;

now, inside of the constructor:


Enemy::Enemy()
{
enemies_in_world.push_back(this);
}


now inside the destructor:


Enemy::~Enemy()
{
enemies_in_world.erase(find(enemies_in_world.begin(),enemies_in_world.end(),this);
}


(will this work? or do i have to overload the == operator for find to work properly? the STL docs werent very clear)

now, since my enemies are always in list's (ie being copied a lot), im not sure how to implement the part with the copy constructor / assignment operator. this is what i got so far:

in the copy constructor:


Enemy::Enemy(const Enemy &cpy)
{
enemies_in_world.push_back(this);
}


and the assignment operator ?


Enemy Enemy::operator = (Enemy cpy)
{

Enemy temp;
enemies_in_world.push_back(&temp);

return temp;
}


so am i doing this right? like i said im very new to op overloading, copy constructors, and using the find() function.. please tell me if i did this right.. thanks again!!

[edited by - graveyard filla on June 10, 2004 4:35:34 AM]

Share this post


Link to post
Share on other sites
Your assigment operator is not a proper assigment operator it should be something like this:


Enemy& Enemy::operator=(const Enemy& cpy) {
return *this;
}


And you have to define an equality operator for find or use a functional object.

this is a member function equality operator:

bool operator==(const Enemy& e) const {
return this->val == e.val;
}


or a non member function version

bool operator==(const Enemy& e1, const Enemy& e2) {
return e1.val == e2.val;
}

Share this post


Link to post
Share on other sites
Hello graveyard filla,

I would have a master map which has as it key the pointer to World_Update base class.
It would then have a class that would have a list of all list that World_Update object is in.

ex.
you create an enemy he gets add to world list and also the world_enemies list.

on each add you go the master world object map use the pointer of the enemy that is geting added.
Then in the list_class return from the map, add the object that is added the enemy.
once for world_update list and world_enemy list.
If this enemy is added to your player he does the same.

If enemy dies you go to the master world object map use it pointer to get it list_class go through each list and remove form each then
erase this object entry and finish delete object.

Then all you would need is each class store in the list_class has the same base class with same add/remove World_Update form internal list.

Do you get my point?

Lord Bart

[edited by - lord bart on June 10, 2004 10:53:56 AM]

[edited by - lord bart on June 10, 2004 11:04:11 AM]

Share this post


Link to post
Share on other sites

  • Advertisement