unique_ptr::get() function with virtual and non-virtual function

692 views Asked by At

I am using VS2012.
I am porting code from raw pointer to unique_ptr and facing a problem.
Here I have tried to simulate the scenario:

class xyz{
  public:
    virtual int getm();
    int get();       
    static std::unique_ptr<xyz> returnbase();
};

class abc:public xyz
{
public:
    int getm() {return 0;}
};

std::unique_ptr<xyz> xyz::returnbase()
{
    std::unique_ptr<xyz> u_Swift(nullptr);
    u_Swift =  std::unique_ptr<xyz>(dynamic_cast<xyz*>(new abc()));
    return u_Swift;
}

int _tmain(int argc, _TCHAR* argv[])
{
    xyz* x1 = xyz::returnbase().get();
    x1->get();
    x1->getm();
    return 0;
}

I get a crash "Access Violation" while calling virtual function.
I am surprised why this is crashing for virtual functions?

Thru watch I can see that virtual pointer is corrupted after assignment. But why this is corrupted, I am curious about.

1

There are 1 answers

0
Kerrek SB On BEST ANSWER

Your x1 is a dangling pointer, because the temporary unique pointer that owns its initial pointee is destroyed at the end of the first statement in main, and the pointee is destroyed as a consequence.

 xyz* x1 = xyz::returnbase().get();
 //        ^^^^^^^^^^^^^^^^^      ^^
 //         temporary object       ^-- destroyed here

To retain the object, you need to make it non-temporary, like this:

int main()
{
    std::unique_ptr<xyz> thing = xyz::returnbase();
    xyz * x1 = thing.get();

    // ... use x1 and *x1 ...

}  // thing goes out of scope and *thing is destroyed