I've manage to narrow down what the problem is and created a test case that simulates my real code.

The problem occurs in a destructor (of B1) when it tries to get a shared pointer to shared_from_this() from its base class (base_class).  I think that  the execution of the destructor hierarchy has deleted the original shared_ptr to B2 meaning that the shared_from_this() returns an error (because shared_from_this() requires that the object is managed by a shared_ptr).

My original destructor code was using raw pointers (ie. this) which worked fine because the base_class destructor was last to be called and was still alive at the time when ~B2() is called. This seems like it could be a limitation of boost::shared_ptr?

I have placed my code in the destructor of B2 because in my program I am never sure exactly of the lifespan of B2.  During execution I accumulate information in the B2 object and then write out this information at the end of its lifespan i.e in the destructor.

I'm open to any ideas including any ways that I might be able to restructure my program.


#include <boost/smart_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/scoped_ptr.hpp>
#include <iostream>

class base_class : public boost::enable_shared_from_this<base_class>
{
        private:
                 boost::shared_ptr<base_class> m_Linked;                        // link to another base_class
        public:
        base_class(){};
        base_class( boost::shared_ptr<base_class> pLinked)
        {
                m_Linked = pLinked;                                                // store link to other base class
        }
};

class B : public base_class
{
public:
        B(boost::shared_ptr<base_class> pLinked) : base_class( pLinked){}
};

class B1 : public B
{
public:
        B1(boost::shared_ptr<base_class> pLinked) : B( pLinked){}
        ~B1()
        {
                try{
                        boost::shared_ptr<base_class> ptr_This = shared_from_this();                // Exception occurs here
                        // Write out some links here.
                }
                catch (exception &e)
                {
                        std::cout << e.what();
                }
        }
};

class B2 : public B1
{
public:
        B2(boost::shared_ptr<base_class> pLinked) : B1( pLinked){}
};

class A : public base_class
{
public:
        A() : base_class(){};
        int f;
        void Process()
        {
                boost::shared_ptr<base_class> ptr_me = shared_from_this();                // get pointer to myself
                                                                        //afterwards - use_count = 2, weak_count = 2
                f = 3;

                if (f == 3){
                        boost::shared_ptr<B2> ptr_b2( new B2(ptr_me) ) ;                        // create new B2 and pass pointer to me.
                }else{                                                        // crashes with bad_weak_ptr error on this line.
                }
        }
};


void main()
{
        boost::shared_ptr<A> ptr_a( new A() );
        ptr_a->Process();
}

// EOF