Exception thrown from destructor

A C++ destructor throws or may throw an exception.

C++ destructors should never throw exceptions for two reasons. First, C++ objects can be torn down implicitly in contexts, where exceptions cannot be allowed. For example, suppose you enter a block and declare an instance of an object X whose destructor will throw an exception E1. Now suppose you exit that block by throwing another exception, E2. The C++ runtime cannot execute the exception handlers for both E1 and E2, and choosing one would effectively lose the other exception. Since losing exceptions is unacceptable, the C++ runtime calls terminate() which normally kills the process immediately.

Second, even if an exception thrown by a destructor is successfully thrown and caught, it is still bad because it causes the application to leak memory. When an object is deleted, two things happen: first the destructor is called and second the delete operator is called. It is the delete operator that actually releases the storage. If the destructor throws an exception the delete operator is never called so you will leak memory.

ID

Observation

Description

1

Exception throw

This shows where the exception is thrown

2

Definition

This shows where the destructor was defined

Example

          
#include <stdio.h>
#include <stdlib.h>

class Bomb { // bad class throws exception from destructor
    int x;
public:
    Bomb() : x(0) {}
    ~Bomb() { throw "boom"; }
    
    void * operator new(size_t n) throw()
    {
        printf("operator new called\n");
        return malloc(n);
    }
    
    void operator delete(void *p) throw()
    {
        printf("operator delete called\n"); // never gets here
        if (p != 0) free(p);
    }
};

void f() {
    Bomb myBomb; // local variable that will blow up when torn down
    
    Bomb *pBomb = new Bomb();
    try {
        delete pBomb;
    } catch (...) {
        // Gets here but leaks storage.  Print output shows that
        // operator new was called but operator delete was not.
        printf("caught exception from destructor\n");
    }
    
    // program dies here: can't throw two exceptions
    // ("boom" and "no boom") at the same time.
    throw "no boom"; // program dies here
}

int main(int argc, char **argv)
{
    try {
        f();
    } catch (char *message) {
        printf("f threw %s\n", message); // never gets here
    }
}
        

Copyright © 2010, Intel Corporation. All rights reserved.