0
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*
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • 1
    This isn't valid C++ (`void main()` and passing a `shared_ptr` to a constructor that's expecting a real pointer), doesn't actually ask a question, and if it did the question would be pointless. – David Thornley Oct 05 '10 at 19:46

1 Answers1

0

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
  • 299,747
  • 42
  • 398
  • 622
  • if Obj_A destructor is called, should "objB.method1()" call crash since it invoked "_objA->method1()" indirectly – user467161 Oct 05 '10 at 19:56
  • ifObj_A* ObjAFactory::createObjA() { boost::shared_ptr objA(new Obj_A()); return objA; } – user467161 Oct 05 '10 at 19:58
  • if i return shared_ptr instead of raw pointer in factory method, will that work – user467161 Oct 05 '10 at 19:59
  • @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 Oct 05 '10 at 20:01
  • Yes, returning a shared_ptr instead of a raw pointer would solve *one* of your problems. – Mark Ransom Oct 05 '10 at 20:02
  • @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 Oct 05 '10 at 20:09
  • thanks for help, i have changed returning of raw pointer to return a shared_ptr, it works. – user467161 Oct 05 '10 at 20:58
  • @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 Oct 05 '10 at 21:16
  • no, i also changed Obj_B constructor to take a shared_ptr instead of raw pointer – user467161 Oct 05 '10 at 23:14