Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shared_ptr with deleter class - why deleter is copied?

Suppose I create a shared pointer with a custom deleter. In the following code I would like to check what happens with the deleter object itself:

struct A {
    A() { std::cout << "A\n"; }
    ~A() { std::cout << "~A\n"; }
};

struct D {
    D() {
        std::cout << "D\n";
    }
    ~D() {
        std::cout << "~D\n";
    }
    D(const D&) {
        std::cout << "D(D&)\n";
    }
    void operator()(A* p) const {
        std::cout << "D(foo)\n";
        delete p;
    }
};

int main()
{
    std::shared_ptr<A> p(new A, D());
}

I see that D(const D&) and ~D() for the "deleter" class are called six more times:

D
A
D(D&)
D(D&)
D(D&)
D(D&)
D(D&)
D(D&)
~D
~D
~D
~D
~D
~D
D(foo)
~A
~D

What happens? Why it needs to be copied so many times?

like image 757
klk206 Avatar asked Dec 18 '19 03:12

klk206


1 Answers

I checked your code with gcc 7.4 and I get the same number of calls to the destructors. What you observe is that the deleter object is moved six times through std::move(deleter).

As you have added a destructor to your class, the automatic generation of the default move semantics is disabled and you need to define them explicitly:

D(D&&) = default;
D& operator=(D&&) = default;

However, even with move semantics the destructor can still be called up to six times.

like image 199
20knots Avatar answered Oct 19 '22 04:10

20knots