# pointer behaviour

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

## Recommended Posts

Hi.

So I came across (what I think is) some wierd pointer behaviour and I was hoping someone around here might be able to explain this behaviour.

1. In the AIObject class I have a public static container that holds various AI entities, such as NPCs or monsters etc.
std::vector<AIObject*> AIObjects;

2. (In the player class I have a target)
DynamicObject* target;

3. When targeting an enemy the target is set:
this->target = AIObject::AIObjectList[activeTarget];
(There's actually a bit more in to selecting the target, but it's unrelated to this problem)

4. You are then able to do various things like casting a spell:
void Player::cast_spell(int type) { if (target != 0) spells.push_back(new Spell(type, this, target)); }

Up to this point it works as I would imagine it should.
For instans, if I switch target it changes the target accordingly and if the target moves out of the screen it gets de-selected and so on.

But whenevever a target gets removed from the AIObjects vector the target member inside the Player class isn't updated accordingly.

5. In the main-loop:
if (!AIObject::AIObjects->is_alive()) { delete AIObject::AIObjects; AIObject::AIObjects = 0; AIObject::AIObjects.erase(AIObject::AIObjects.begin() + i); }

6. But in the player class:
void Player::show_active_target() { if (target != 0) { // this still gets exectued } }

I was under the impression that since the target pointer in the Player class is pointing to an AIObject in the AIObjects vector if the AIObject being pointed at were to get deleted so would the pointee?

I've found a work-around:
if (target != 0) if (!target->is_alive()) target = 0;

But this isn't a very elegant solution and I would much rather understand why the target pointer isn't updated accordingly.
(For the record, Player and AIObject share the same base-class (DynamicObject) and the actual target is of type Monster which is a derrived class of AIObject.)

##### Share on other sites

I was under the impression that since the target pointer in the Player class is pointing to an AIObject in the AIObjects vector if the AIObject being pointed at were to get deleted so would the pointee?

Why would it? The vector stores a copy of the pointer you pushed into it. No operation on the pointer in the vector will affect any other pointers in the program. It's like how if you store an int in the vector, operating on the int in the vector won't affect any other int in the program.

##### Share on other sites
If you delete an object, not all pointers to it are automatically set to 0. This would be very convenient, but that's not how it works.

The simplest, but also pretty dangerous solution would be to manually set every reference to the deleted object to 0 manually.

Alternatively, you can add another layer of abstraction, i.e. a "shared_ptr". This would ensure, that as long as something is pointing to the object, it does not get deleted. This is probably not what you want, but there's also a standard solution for that. For references that should not keep the object alive, use "weak_ptr".

Here's a quick tutorial that google spat out after a quick search:
http://cppguru.wordpress.com/2009/01/05/c-weak-pointers/

I hope that helps!

##### Share on other sites

Ah SirCrane, makes a lot of sense. I think that I was thinking about it backwards.. The target pointer in the player class affects the one in the AIObjects vector but not the other way around.. I see it more clearly now

Rattenhirn, thanks! I am aware of shared_ptr but I've only used them for the ownership or reference counting properties.

Alternatively, you can add another layer of abstraction, i.e. a "shared_ptr". This would ensure, that as long as something is pointing to the object, it does not get deleted. This is probably not what you want, but there's also a standard solution for that. For references that should not keep the object alive, use "weak_ptr".

Aha! So by this I guess the AIObjects vector would be:
std:.vector<std::tr1::shared_ptr<AIObject> > AIObjects
And the target-pointer in the Player class:
std:.vector<std::tr1::weak_ptr<AIObject> > target
?

I'll check that tutorial out right away.

Thanks again guys Edited by AlanSmithee

##### Share on other sites
Looks ok, but in you original code, "target" was just a single pointer and now it's a vector of pointers.

##### Share on other sites
Ah was a typo, sorry

##### Share on other sites

Ah SirCrane, makes a lot of sense. I think that I was thinking about it backwards.. The target pointer in the player class affects the one in the AIObjects vector but not the other way around.. I see it more clearly now

That still doesn't sound like you're "getting it". Neither pointer effects one another; both the pointer that is stored as a field in the player instance, and the pointer that is stored in the vector, are just pointers. They are just integers, who happen to be storing the memory address of some object instance in memory. When performing operations on those pointers, you are altering that instance. If you set the pointer that is a field to nullptr, such will not change the one in the vector, and vice versa.

Your initial solution is dangerous and undefined behavior. Why?
if (!target->is_alive())

You've already deleted the object that 'target' points to. If is_alive happens to work, great, but it's still undefined and shouldn't be relied upon. Once the memory where 'target' points to is overwritten, that will no longer function properly.

The proper two ways are (as has already been said):

A, Send out some kind of signal to objects that said object has been deleted, so that they may remove references to it.

EDIT: I missed a word.

##### Share on other sites
Hi Amesie.
Thanks for taking your time to clarify this.

I had a fealing I still wasn't understanding it properly, becaus when I thought something would act according to my prior statement, it did not.

I had some problems implementing the weak_ptr/shared_ptr paradigm so I did some testing with a simple class hierarchy in a console enviroment passing around shared_ptr's and managing them via weak_ptr's inside the class objects and now I finally understand how it works and how well that design would fit my needs so I'm going to implement it tomorrow!

Thanks again folks =)

Edit: bird?

Edit 2: Got it working now with the smart pointers so woho~ =) Edited by AlanSmithee

1. 1
2. 2
Rutin
24
3. 3
4. 4
JoeJ
18
5. 5

• 14
• 22
• 11
• 11
• 9
• ### Forum Statistics

• Total Topics
631766
• Total Posts
3002215
×

## Important Information

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!