问题
unsure how to go about describing this but here i go:
For some reason, when trying to create a release build version of my game to test, the enemy creation aspect of it isn't working.
Enemies *e_level1[3];
e_level1[0] = &Enemies(sdlLib, 500, 2, 3, 128, -250, 32, 32, 0, 1);
e_level1[1] = &Enemies(sdlLib, 500, 2, 3, 128, -325, 32, 32, 3, 1);
e_level1[2] = &Enemies(sdlLib, 500, 2, 3, 128, -550, 32, 32, 1, 1);
Thats how i'm creating my enemies. Works fine when in the debug configuration but when i switch to the release config, it doesn't seem to initialize the enemies correctly.
To me, this seems a bit strange that it works in debug but not in release, any help appreciated on what mostly is what i've done wrong.
回答1:
Other people have already pointed out the error, namely that the temporaries are getting destroyed straight away, but all of the answers so far are using manual memory management - it's more idiomatic in C++ to use e.g. std::vector
for something like this, e.g.
std::vector<Enemies> enemies;
enemies.push_back(Enemies(sdlLib, 500, 2, 3, 128, -250, 32, 32, 0, 1));
enemies.push_back(Enemies(sdlLib, 500, 2, 3, 128, -325, 32, 32, 3, 1));
enemies.push_back(Enemies(sdlLib, 500, 2, 3, 128, -550, 32, 32, 1, 1));
Then you just access the Enemies
instances as enemies[0]
through enemies[2]
and they get cleaned up automatically when the vector goes out of scope.
回答2:
e_level1[0] = &Enemies(sdlLib, 500, 2, 3, 128, -250, 32, 32, 0, 1);
doesn't do what you think it does. If it is the constructor call, it creates a temporary and its address is stored in e_level1[0]. When e_level1[1] is initialized e_level1[0] destructor is probably already called.
You probably want to do
Enemies* e_level1[3] =
{
new Enemies(sdlLib, 500, 2, 3, 128, -250, 32, 32, 0, 1) ,
new Enemies(sdlLib, 500, 2, 3, 128, -325, 32, 32, 3, 1) ,
new Enemies(sdlLib, 500, 2, 3, 128, -550, 32, 32, 1, 1)
};
回答3:
Most debug modes initialise all memory to zero for you. In normal execution it may be random.
Make your compiler as fussy as possible (you should have done this already) and fix all the warnings.
If it still persists, you should run it in a memory checking tool like valgrind.
回答4:
The code initializes the pointers to point to temporary objects that are immediately destroyed. Accessing temporaries that no longer exist through pointers or references is undefined behavior. You want:
Enemies *e_level1[3];
e_level1[0] = new Enemies(sdlLib, 500, 2, 3, 128, -250, 32, 32, 0, 1);
e_level1[1] = new Enemies(sdlLib, 500, 2, 3, 128, -325, 32, 32, 3, 1);
e_level1[2] = new Enemies(sdlLib, 500, 2, 3, 128, -550, 32, 32, 1, 1);
回答5:
You seem to be creating the Enemies object on the stack, which means that the moment they go out of scope, your e_level1 pointers are pointing to objects that have been destroyed. (proof: put a breakpoint in the Enenmies class destructor and seee when that gets hit) Therefore, when you try to de-reference them, you'll get garbage.
What you want is:
for( size_t i = 0; i < 3; i++ )
e_level1[i] = new Enemies( sdlLib, ... );
That will create the object on the heap. It also means you will need to destroy the objects using:
for( size_t i = 0; i < 3; i++ )
delete ( e_level + i );
来源:https://stackoverflow.com/questions/8044549/issue-with-pointers-only-in-release-build