0

I'm quite new to smart pointers and I encountered a problem with the code below

#include <memory>
#include <vector>

using namespace std;

class A
{
public:
    int var;
};

class B : public A
{
public:
    vector<unique_ptr<int>> vec;
};

int main() 
{
    {
        unique_ptr<B> b(new B);
        b->vec.push_back(unique_ptr<int>(new int(4)));
        unique_ptr<A> a = unique_ptr<A>(move(b));
    }

    system("pause");

    return 0;
}

In this example the 4 added to vector vec is not deleted when pointer a goes out of scope, but when I change it so that it doesn't cast to base class then all resources are returned as intended, how do I manage deleting variables defined in derived classes when using polymorphism and unique_ptr?

Werem
  • 21
  • 2
  • 2
    `A` needs to have an accessible (e.g. `public`) virtual destructor. Otherwise, when `unique_ptr` cleans up (using operator `delete`) the behaviour is undefined. A memory leak is one possible consequence of that (other consequences are possible, when behaviour is undefined). – Peter Jul 27 '18 at 23:00
  • @Peter is it just UB whenever an object goes away but its appropriate destructor is never called? I always thought it would just run the destructor for A and move on (and maybe that's what tends to happen in practice) – xaxxon Jul 27 '18 at 23:08
  • @xaxxon • I believe you are correct that the A::~A is called, and moves on. – Eljay Jul 27 '18 at 23:12
  • 1
    @xaxxon - The undefined behaviour occurs with use of operator `delete`, which is what `unique_ptr` does by default. Essentially, the code is wrapping the sequence `A *p = new B; delete p;` which gives undefined behaviour if `A` does not have a virtual destructor. If the compiler knows the actual type of the object, the behaviour is well-defined. For example; `B *p = new B; delete p;` is perfectly well defined. – Peter Jul 27 '18 at 23:12
  • 1
    @Eljay - practically, compilers MAY call the destructor of `A` (and, practically, a fair few compilers do in simple cases like this). The behaviour is undefined, so the standard does not require them to. – Peter Jul 27 '18 at 23:15

0 Answers0