C++ Destroying an object that has already been destroyed


Example

In this example, a destructor is explicitly invoked for an object that will later be automatically destroyed.

struct S {
    ~S() { std::cout << "destroying S\n"; }
};
int main() {
    S s;
    s.~S();
} // UB: s destroyed a second time here

A similar issue occurs when a std::unique_ptr<T> is made to point at a T with automatic or static storage duration.

void f(std::unique_ptr<S> p);
int main() {
    S s;
    std::unique_ptr<S> p(&s);
    f(std::move(p)); // s destroyed upon return from f
}                    // UB: s destroyed

Another way to destroy an object twice is by having two shared_ptrs both manage the object without sharing ownership with each other.

void f(std::shared_ptr<S> p1, std::shared_ptr<S> p2);
int main() {
    S* p = new S;
    // I want to pass the same object twice...
    std::shared_ptr<S> sp1(p);
    std::shared_ptr<S> sp2(p);
    f(sp1, sp2);
} // UB: both sp1 and sp2 will destroy s separately
// NB: this is correct:
// std::shared_ptr<S> sp(p);
// f(sp, sp);