views:

20

answers:

1
class Obj_A {
public:
    ~Ojb_A() {
         cout << "calling Obj_A() destructor\n";
     }
    void method1() {
         cout << "invoking Obj_A::method1()\n";
    }
};

class Obj_B {
    boost::shared_ptr<Obj_A> _objA;
public:
    Obj_B(Obj_A *objA) {
        _objA.reset(objA)
     }

    void method1() { _objA->method1(); }
};

class ObjAFactory {
public 
    static Obj_A* createObjA();
};

Obj_A* ObjAFactory::createObjA() {
    boost::shared_ptr<Obj_A> objA(new Obj_A());
    return objA.get();
}

void main() {
    boost::shared_ptr<Obj_A> objA(ObjAFactory::createObjA());
    Obj_B objB(objA);
    objB.method1();
}

Output:

*calling Obj_A() destructor
invoking Obj_A::method1()
calling Obj_A() destructor
calling Obj_A() destructor
a.out in free(): warning: page is already free
a.out in free(): warning: page is already free*
A: 

When createObjA returns, the shared_ptr goes out of scope and destructs the object. You're now returning an invalid pointer.

The Obj_B constructor is taking a copy of the pointer. When that object is destroyed, the shared_ptr will try to destroy it again.

When main() exits, the third shared_ptr is destroyed and another attempt is made to destroy the invalid pointer.

Mark Ransom
if Obj_A destructor is called, should "objB.method1()" call crash since it invoked "_objA->method1()" indirectly
ifObj_A* ObjAFactory::createObjA() { boost::shared_ptr<Obj_A> objA(new Obj_A()); return objA;}
if i return shared_ptr instead of raw pointer in factory method, will that work
@user467161, _objA->method1 can appear to work under certain circumstances. See http://stackoverflow.com/questions/2474018/when-does-invoking-a-member-function-on-a-null-instance-result-in-undefined-behav
Mark Ransom
Yes, returning a shared_ptr instead of a raw pointer would solve *one* of your problems.
Mark Ransom
@user467161: Multiply freeing memory is undefined behavior, and so the Standard puts no requirements on what happens. An implementation is free to check for it and crash or whatever, but the ones I've seen don't do that. Usually, it just corrupts the heap and leads to inexplicable problems later in the program.
David Thornley
thanks for help, i have changed returning of raw pointer to return a shared_ptr, it works.
@user467161 I hope that's not all you did, there's still another bug in the code you posted. Look at my answer carefully.
Mark Ransom
no, i also changed Obj_B constructor to take a shared_ptr instead of raw pointer