Page 1 of 1
[SOLVED]Deleting Objects
Posted: Wed May 18, 2011 3:33 pm
by like80ninjas
Okay, I so I have lots of Entities in my game, ranging from the player to enemies and powerups. I add them to an entity vector that I can iterate through for their think and draw calls, the issue I'm having is that when I call delete or their destructors, the program crashes, and the debugger points at the think or draw function being called by the iterator so i'm assuming the vector still thinks it's there and isn't removed?
How can I cause something to be removed from my vector list right when it's destroyed so I can effectively "kill" enemies and get rid of picked up power ups? Or is their a container I should be using other than vector for this?
Thanks for any help you can provide!
Re: Deleting Objects
Posted: Wed May 18, 2011 3:38 pm
by Ginto8
The vector should be storing pointers to your Entities, and once you delete an entity you should make the pointer to it NULL. Also, in any function that uses your entities you should make sure it's not null before you use it.
Re: Deleting Objects
Posted: Wed May 18, 2011 4:35 pm
by bnpph
Ginto8 wrote:The vector should be storing pointers to your Entities, and once you delete an entity you should make the pointer to it NULL. Also, in any function that uses your entities you should make sure it's not null before you use it.
No, the vector stores what you told it to.
vector<class> is defined to be an array of classes. Setting the iterator to NULL here will be undefined behavior - don't do it.
vector<class*> is pointers to classes.
If you want to delete an entity in a vector, you use vector::erase and never call the object's destructor, as the vector does so.
If your vector is of pointers, then call the destructor after dereferencing, then you can either erase the vector element, or set it to NULL. If you set it to NULL, it is important for you to later go through and remove every NULL element.
Keep in mind that vector::erase happens in O(n) time.
Re: Deleting Objects
Posted: Wed May 18, 2011 4:37 pm
by XianForce
Adding to what Ginto said, when you are adding entities to the vector, it's also a good idea to loop through them, and check to see if there's a NULL pointer, if so, assign the value of your entity pointer to that NULL pointer. That way you don't always have to reallocate the vector when you add an entity.
Re: Deleting Objects
Posted: Wed May 18, 2011 4:42 pm
by bnpph
XianForce wrote:Adding to what Ginto said, when you are adding entities to the vector, it's also a good idea to loop through them, and check to see if there's a NULL pointer, if so, assign the value of your entity pointer to that NULL pointer. That way you don't always have to reallocate the vector when you add an entity.
Keep in mind that this require you run through every element until you find a NULL, and so this may get worse performance than a simple push_back - especially if no realloc is needed.
Re: Deleting Objects
Posted: Wed May 18, 2011 4:48 pm
by XianForce
bnpph wrote:XianForce wrote:Adding to what Ginto said, when you are adding entities to the vector, it's also a good idea to loop through them, and check to see if there's a NULL pointer, if so, assign the value of your entity pointer to that NULL pointer. That way you don't always have to reallocate the vector when you add an entity.
Keep in mind that this require you run through every element until you find a NULL, and so this may get worse performance than a simple push_back - especially if no realloc is needed.
That's very true. Really depends on how many entities you have though. That wouldn't be the case unless the vector was real large :p.
Re: Deleting Objects
Posted: Wed May 18, 2011 5:28 pm
by like80ninjas
Thanks for all the replies! I'd like to clarify that it is a vector of pointers to an Entity class, and that I do check if things aren't NULL before doing things with them, but for some reason when I use delete or call a destructor it still crashes. Now, I think that calling erase is the way I'd like to go as it supposedly calls the destructor for the object as well right? How would I figure out if the current value of the iterator is equal to the instance I'm trying to delete and then erase it?
Re: Deleting Objects
Posted: Wed May 18, 2011 5:56 pm
by bnpph
like80ninjas wrote:Thanks for all the replies! I'd like to clarify that it is a vector of pointers to an Entity class, and that I do check if things aren't NULL before doing things with them, but for some reason when I use delete or call a destructor it still crashes. Now, I think that calling erase is the way I'd like to go as it supposedly calls the destructor for the object as well right? How would I figure out if the current value of the iterator is equal to the instance I'm trying to delete and then erase it?
erase will call the destructor of the pointer, not the object it is pointing to. You will have to call delete on the actual object too.
Also, delete and destructor are different. delete can be described as a calling "free()" and "destructor" - the destructor does not free the memory. You should only use the destructor by its self when writing things like memory containers.
To see if an object is equal to an iterator, just check to see if the object's pointer is equal to the iterator, as iterators are just pointers.
if((Object*)&object == iter) { .... } (I think this should work without casts)
It is crashing probably because you are using delete wrong, if you post the code I can look at it.
Re: Deleting Objects
Posted: Wed May 18, 2011 6:24 pm
by like80ninjas
I figured it out using what you guys have told me so far, thanks guys!
Re: Deleting Objects
Posted: Thu May 19, 2011 1:08 pm
by Falco Girgis
XianForce wrote:bnpph wrote:XianForce wrote:Adding to what Ginto said, when you are adding entities to the vector, it's also a good idea to loop through them, and check to see if there's a NULL pointer, if so, assign the value of your entity pointer to that NULL pointer. That way you don't always have to reallocate the vector when you add an entity.
Keep in mind that this require you run through every element until you find a NULL, and so this may get worse performance than a simple push_back - especially if no realloc is needed.
That's very true. Really depends on how many entities you have though. That wouldn't be the case unless the vector was real large :p.
I really don't recommend that... You should just let the container do its job and use it the way it should be used. You're just doing additional, unnecessary processing like this.
If the reallocation overhead of a vector is a concern, why bother even using STL anyway? Use your own container.