samedi 12 août 2017

Why is an overloaded delete not called when an exception is thrown in a destructor?

I've written the below code which overloads the new and delete operators and throws an exception in the destructor.

When the exception is thrown, why is the code in the delete operator not executed (and "bye" printed)?

If it shouldn't be executed, (how) is the memory freed? Is one of the other delete operators called? Would overloading one of them instead result in the corresponding code being executed?

#include <iostream>
using namespace std;
class A
{
public:
    A() { }
    ~A() noexcept(false) { throw exception(); }
    void* operator new (std::size_t count)
    {
        cout << "hi" << endl;
        return ::operator new(count);
    }
    void operator delete (void* ptr)
    {
        cout << "bye" << endl;
        return ::operator delete(ptr);
    }
    // using these (with corresponding new's) don't seem to work either
    // void operator delete (void* ptr, const std::nothrow_t& tag);
    // void operator delete (void* ptr, void* place);
};

int main()
{
    A* a = new A();
    try
    {
        delete a;
    }
    catch(...)
    {
        cout << "eek" << endl;
    }
    return 0;
}

Output:

hi
eek

Live demo.

I looked at:

But I couldn't find an answer to what exactly happens (1) for an exception in the destructor (as opposed to the constructor) and (2) with custom destructors.

I don't need a lecture on this being bad practice - I just ran into this code and I'm curious about the behaviour.

Aucun commentaire:

Enregistrer un commentaire