Sign in to follow this  
Sean_Seanston

Pointer pointing to garbage I think - May be vector-related

Recommended Posts

Sean_Seanston    880
Long story short, I have this situation in my game: There's a vector of enemy objects (called AIEntityController) and these objects each have a vector of Entity* where Plane is a class that inherits from Entity. When an enemy is spawned, it looks like this:
AIEntityController ai( gameWorld.getAIType( type ), b );

spawnEnemy( ai, x, y );

Where spawnEnemy does push_back( ai ) on the vector of enemies and also calls the initialization function of the ai object. Here is where the problem seems to lie... The initialization function looks like this:
	Entities.push_back( new Plane( this, x, y, gameWorld.getPlaneType( eType->getPlane() ) ) );
	( *Entities.back() ).init();

So I'm pushing a Plane* onto the AIEntityController's entity vector with various parameters including most importantly the this pointer to the calling AIEntityController. Then I'm dereferencing the Plane* (I don't need to cast to Plane* from the base class do I?) and calling its own init() function. Now, I've looked at the enemies vector and all seems well there. However, what I'm using the pointer from the Plane to the AIEntityController for is to check a variable I need to be able to read (at least using my current system) from the Plane. However, some but bizarrely not all of these pointers result in giving me garbage data. I call the function at the end of the pointer and most give me the 1 or 0 that it should be but some (always the 3rd enemy for some reason when there are at least 4 as an example) give -84324234 or some other garbage value. So, it seems that I haven't done the assigning of the pointer properly but I can't figure out how else to do it. Given that the AIEntityController is already on the vector when it then passes its this pointer to the Plane, I thought that would be ok and indeed sometimes it does work. I know that passing a pointer to an object in a vector is a bad idea but how else might I handle this situation? Should I just find any other way to do it without passing the pointer into the plane's constructor? As for 3 enemies working but not 4, might it be that the vector is changing around and the pointer to the 3rd is getting invalidated which is causing the pointer to point to garbage? I really should have been more careful with pointing to vectors.

Share this post


Link to post
Share on other sites
stonemetal    288
Are all of your vectors storing pointers or are they storing objects directly? If they are storing objects directly then there is your problem. Vectors are free to move stuff whenever they feel like it(on re-size usually.) The way around this is to either store pointers in your vectors or store vector indexes instead of pointers.

Share this post


Link to post
Share on other sites
Palidine    1315
Why do you have an init function that needs to be called separately from the constructor? Why isn't the init logic simply in the constructor?

You also don't need the insane syntax. This should work fine and is a trillion times easier to debug:

Plane *plane = new Plane( this, x, y, gameWorld.getPlaneType( eType->getPlane() ) );
plane->init(); //though this should really be inside the constructor.
Entities.push_back(plane);



Quote:
Original post by Sean_Seanston
I know that passing a pointer to an object in a vector is a bad idea but how else might I handle this situation?

Why? Other than having to manage "bad" pointers and object lifetime there's nothing inherrently wrong with storing pointers in a vector.

-me

Share this post


Link to post
Share on other sites
Palidine    1315
Anyway. Where is your app actually accessing the garbage data? Is it in the exact code you posted or is it somewhere else?

-me

Share this post


Link to post
Share on other sites
Sean_Seanston    880
Quote:
Original post by stonemetal
Are all of your vectors storing pointers or are they storing objects directly? If they are storing objects directly then there is your problem. Vectors are free to move stuff whenever they feel like it(on re-size usually.)


Let's see...

The vector of Entities that is contained within AIEntityController stores pointers to Entity objects.
However, the AIEntityController objects (indeed the object that it appears is getting moved or otherwise can't be found) are stored in a vector of objects.

Think it might be as simple as that?

Along that line though, would I then be perfectly fine to store pointers in a vector and then assign other pointers to point to the same location as one in the vector without fearing that it would be ruined by the vector reorganizing? I was under the impression that it'd still be dangerous but then it seems logical that it would be fine...

Sounds like that's the problem alright.

Quote:
Original post by Palidine
Why do you have an init function that needs to be called separately from the constructor? Why isn't the init logic simply in the constructor?


I think I was being careful to make absolutely sure there was nothing in the constructor that could reference something that wasn't created before the constructor was called.

Though it's probably pointless for that object but I suppose it's just a bad habit I got into after too many bad experiences doing things inside constructors that caused errors.

Quote:
Original post by Palidine
Why? Other than having to manage "bad" pointers and object lifetime there's nothing inherrently wrong with storing pointers in a vector.

-me


No, I mean having a pointer point to an object that's inside a vector. Since the vector could move the object and you wind up pointing somewhere wrong.

Quote:
Original post by Palidine
Anyway. Where is your app actually accessing the garbage data? Is it in the exact code you posted or is it somewhere else?

-me


Somewhere else.

I made a slight change though. Following your suggestion to incorporate the init function of the Plane into the constructor, I did that for the AIEntityController class since it seemed to make more sense.

Now it still doesn't work but instead of only some enemies going weird, they now all do. Probably a good sign I imagine that at least it's now consistent, whatever's happening.

Anyway, sounds like it's probably that I'm storing the AIEntityController objects as objects in a vector and then pointing to them, do you think? Maybe I should change them to pointers?

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