Search code examples
c++smart-pointersunique-ptr

Destructor called unexpectedly


Why is the destructor ~TestClass() in this simple code called twice?

#include <memory>
#include <iostream>
#include <vector>

class TestClass
{
  int m_val;

public:
  TestClass(int val);
  ~TestClass();
};

TestClass::TestClass(int val) : m_val(val)
{
  std::cout << this << " TestClass() " << m_val << "\n";
}

TestClass::~TestClass()
{
  std::cout << this << " ~TestClass() " << m_val << "\n";
  m_val = -1;
}

int main()
{
  auto x = std::make_unique<TestClass>(2);

  auto y = *x;  // <<<< this triggers it
}

Output

000001E66C0B5980 TestClass() 2
00000057FDD9FAB4 ~TestClass() 2   // why is the destructor called here?
000001E66C0B5980 ~TestClass() 2

Solution

  • auto y = *x; // <<<< this triggers it

    The above is copy initialization and would use copy constructor of the class. The extra destructor call that you're seeing is corresponding to this object y. You can also verify this by adding a copy ctor to your class and you'll notice that the copy ctor is used to create y using *x.

    class TestClass
    {
      int m_val;
    
    public:
      TestClass(int val);
      ~TestClass();
       //added this copy ctor
      TestClass(const TestClass &p): m_val(p.m_val)
    //-------------------------------^^^^^^^^^^^^^^--->use member initializer list
      {
          std::cout << this << " copy ctor " << m_val << "\n";
      }
    };
    //other code as before