Search code examples
c++pointersauto-ptrboost-smart-ptr

My Auto Pointer works even after ownership transfer


As far as I know, auto_ptr works on the concept of transfer of ownership. Also, once an auto pointer transfer its ownership to another auto pointer, it should not be able refer to the object it points to anymore. However, this is not the case I found as shown in the below program. Am I missing something? Please help.

#include <iostream>
#include <string>
#include <memory>

class A
{
    public:
    void display(){
       std::cout << "Inside class A" << std::endl;
    }
};

int main()
{
    std::auto_ptr<A> p1(new A());
    std::auto_ptr<A> p2;
    std::cout << p1.get() << std::endl;
    p2=p1; 

    std::cout << p2.get() << std::endl;
    p2->display();

    std::cout <<p1.get()<< std::endl;  //Address of shows 0 as expected
    p1->display();                     //L1

    std::auto_ptr<A> p3 = p1; //L2
    std::cout << p3.get() << std::endl;  //Address shows 0 as expected
    p3->display(); 

    return 0;
}

Output:
0x45a0620
0x45a0620
Inside class A
0
Inside class A
0
Inside class A

Line L1: How does this work, since p1 do not have the ownership anymore?

Line L2: How does this work, since p1 do not have the ownership anymore?


Solution

  • Your code doesn't show what you think it does.

    This is straightforward Undefined Behaviour: the auto_pointer here is only obscuring the fact that your code reduces to:

    A *a {nullptr};
    a->display();
    

    Consider method A::display - it isn't virtual, so is essentially a simple function whose name has class scope, and which receives through some mechanism an implicit this pointer to the object on which it was invoked.

    Since the function address doesn't depend on the object pointer, your compiled has emitted code which calls the function successfully, just with this==nullptr.

    If you display prints the value of this, or use a non-static data member of A inside the function, this should be apparent.


    Finally, as NathanOliver pointed out, auto_pointer is deprecated anyway and for good reason.