Problems when casting 'this' to 'shared_ptr'

Started by
2 comments, last by rip-off 13 years, 8 months ago
Hi. I've got a function which takes a shared_ptr as an argument. I want to use 'this' when calling it from a constructor. Like this:

typedef std::shared_ptr<EventListener> EventListenerPtr;BounceComponent::BounceComponent(ActorId actorId, App* app, MovementComponentPtr movementPtr) : Component(actorId, app), movementPtr(movementPtr){  app->getEventManager()->addListener((EventListenerPtr) this, typeid(CollisionEvent).hash_code());}

BounceComponent inherits from EventListener.

When closing the application I get an error message saying:
Unhandled exception at 0x00f3362c in wPong.exe: 0xC0000005: Access violation reading location 0xfeeefeee.

Probably due to freeing already freed memory.

If I remove the call to addListener() from the constructor and place it in my init() function, right after creating the BounceComponent like this:
typedef std::shared_ptr<BounceComponent> BounceComponentPtr;BounceComponentPtr bounce3(new BounceComponent(3, this, movement3));getEventManager()->addListener(static_cast<EventListenerPtr> (bounce3), typeid(CollisionEvent).hash_code());

everything works.

I guess it's the cast of 'this' to a shared_ptr that's causing the problem. How can I solve this? I'd really like for the object to add it self to the event listener when created.
/Peter Welzien
Advertisement
Did you try using enable_shared_from_this?
If I use enable_shared_from_this() the program crashes with error message: bad_weak_ptr.

Could it be that I try to add it to the EventListener during BouceComponent's constructor and the BounceComponent object isn't completly constructed yet?

edit:
I've tried moving
app->getEventManager()->addListener(this->shared_from_this(), typeid(CollisionEvent).hash_code());

To a separate function and call it directly after creating the BounceComponent object. This works.
/Peter Welzien
Firstly, this should be a chance for you to learn that you must be extremely careful when you try to cast pointers. It is very easy to make a mistake that will go unnoticed but cause memory corruption in some unrelated part of the code.

Never cast pointers unless you know why you are doing it. Always use the C++ cast operators so the compiler will try to warn you if it cannot support the type of cast you logically want.

Quote:
If I use enable_shared_from_this() the program crashes with error message: bad_weak_ptr.

Could it be that I try to add it to the EventListener during BouceComponent's constructor and the BounceComponent object isn't completly constructed yet?

Yes. This is covered by the enable_shared_from_this documentation (emphasis mine):
Quote:
Requires: enable_shared_from_this<T> must be an accessible base class of T. *this must be a subobject of an instance t of type T . There must exist at least one shared_ptr instance p that owns t.

Until the constructor completes, no shared_ptr<> could be owning the object.

This topic is closed to new replies.

Advertisement