Sign in to follow this  
nano511

After destructor is called,

Recommended Posts

nano511    103
Everytime i 'kill' a monster i delete it. After its destructor is called i get this..
[code]
Unhandled exception at 0x68129397 in MyGame.exe: 0xC0000005:
Access violation reading location 0xfeeeff26.
[/code]

Share this post


Link to post
Share on other sites
Wooh    1088
Do you call delete twice on the same pointer or something? It's just a guess because it's hard to know by just looking at that error message.

Share this post


Link to post
Share on other sites
broady    119
[quote name='nano511' timestamp='1313109749' post='4848028']
hmm.. maybe? Is there a way to check that? like.. if( not deleted){ delete }
[/quote]

From what i khnow there is no way to do it. You cannot check if you have alreasy called delete on a pointer.

Generally the idea is: if someone allocates memory, that someone has to free it.

Share this post


Link to post
Share on other sites
Bregma    9202
No. There is no way to tell. That's the exciting challenge of C++. It's also why smart pointers were invented. Smart pointers mean you never have to explicitly call delete again.

Share this post


Link to post
Share on other sites
speciesUnknown    527
[quote name='Bregma' timestamp='1313110410' post='4848032']
No. There is no way to tell. That's the exciting challenge of C++. It's also why smart pointers were invented. Smart pointers mean you never have to explicitly call delete again.
[/quote]

I agree. Get the hang of using shared_ptr and weak_ptr and you wont look back.

Share this post


Link to post
Share on other sites
Wooh    1088
I know from your previous posts that you store monster pointers in a vector. If you delete the monster from the vector you probably also want to remove the pointer from the vector. One way of doing that is to use std::vector::erase. It takes an iterator as argument but I'm not going to explain iterators now so I just give some code.
[code]for(std::size_t i = 0; i < monsters.size(); i++ )
{
if(monsters[i]->IsDead())
{
delete monsters[i];
monsters.erase(monsters.begin() + i); // this removes the pointer from the vector
}
}[/code]
Note that all monster after the deleted monster will move down one index in the vector and the size of the vector will be one smaller.

Share this post


Link to post
Share on other sites
nano511    103
Thanks for that Wooh! But that doesnt change the fact that after the destructor is finished, i get that error.

EDIT: Oh... nvm your suggestion did fix it!

Share this post


Link to post
Share on other sites
nano511    103
Just one last question for tonight:

When a monster dies i do this "player->points += 100". But since after the monster dies that will always be true, it keeps adding 100 each frame. How do i stop that?

Share this post


Link to post
Share on other sites
Wooh    1088
You mean IsDead() is always true? When the monster has been deleted you never call IsDead() on it again so that shouldn't cause any problems I think. I can't see your code so I just speculating.

Share this post


Link to post
Share on other sites
rip-off    10976
[quote]
It's just a guess because it's hard to know by just looking at that error message.
[/quote]
The error message has [url="http://www.nobugs.org/developer/win32/debug_crt_heap.html"]secret information embedded in it[/url]. The value 0xfeeefeee (and values nearby) are a special pattern the debug runtime uses.

The value 0xfeeeff26 is an offset into 0xfeeefeee, so this is most likely a use after free bug.

[quote name='Wooh' timestamp='1313110976' post='4848035']
I know from your previous posts that you store monster pointers in a vector. If you delete the monster from the vector you probably also want to remove the pointer from the vector. One way of doing that is to use std::vector::erase. It takes an iterator as argument but I'm not going to explain iterators now so I just give some code.
[code]for(std::size_t i = 0; i < monsters.size(); i++ )
{
if(monsters[i]->IsDead())
{
delete monsters[i];
monsters.erase(monsters.begin() + i); // this removes the pointer from the vector
}
}[/code]
Note that all monster after the deleted monster will move down one index in the vector and the size of the vector will be one smaller.
[/quote]
Wooh's code will skip one monster where two are dead in a row.

Consider the following monster array: [live1, dead1, dead2, live2]. When i == 1, we see the current monster is dead. We remove this monster, and increment i.

Our array now looks like: [live1, dead2, live2]. But i == 2, which is live2. We never test dead2! Of course, such monsters will be removed eventually as this will likely be called every frame. But unless the rest of your code takes into account whether the monster is dead, you could end up with strange bugs.

The following slight modification to the loop will clear all dead monsters every frame:
[code]
for(std::size_t i = 0; i < monsters.size(); /* Handled in loop body */ )
{
if(monsters[i]->IsDead())
{
delete monsters[i];
monsters.erase(monsters.begin() + i); // this removes the pointer from the vector
}
else
{
++i;
}
}
[/code]
This is a manual version of the "remove/erase" idiom, which I would recommend if you weren't using raw pointers in your vector. For the record, I recommend you use a smart pointer like std::shared_ptr in your vector.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this