Under what circumstances are C++ destructors not going to be called?
Solution 1:
Are there any other circumstances where they[destructors] will not be called?
- Long jumps: these interfere with the natural stack unwinding process and often lead to undefined behavior in C++.
- Premature exits (you already pointed these out, though it's worth noting that throwing while already stack unwinding as a result of an exception being thrown leads to undefined behavior and this is why we should never throw out of dtors)
- Throwing from a constructor does not invoke the dtor for a class. This is why, if you allocate multiple memory blocks managed by several different pointers (and not smart pointers) in a ctor, you need to use function-level try blocks or avoid using the initializer list and have a try/catch block in the ctor body (or better yet, just use a smart pointer like scoped_ptr since any member successfully initialized so far in an initializer list will be destroyed even though the class dtor will not be called).
- As pointed out, failing to make a dtor virtual when a class is deleted through a base pointer could fail to invoke the subclass dtors (undefined behavior).
- Failing to call matching operator delete/delete[] for an operator new/new[] call (undefined behavior - may fail to invoke dtor).
- Failing to manually invoke the dtor when using placement new with a custom memory allocator in the deallocate section.
- Using functions like memcpy which only copies one memory block to another without invoking copy ctors. mem* functions are deadly in C++ as they bulldoze over the private data of a class, overwrite vtables, etc. The result is typically undefined behavior.
- Instantiation of some of smart pointers (auto_ptr) on an incomplete type, see this discussion
Solution 2:
The C++ standard says nothing about how specific signals must be handled - many implementations may not support SIGINT
, etc. Destructors will not be called if exit()
or abort()
or terminate()
are called.
Edit: I've just had a quick search through the C++ Standard and I can't find anything that specifies how signals interact with object lifetimes - perhaps someone with better standards-fu than me could find something?
Further edit: While answering another question, I found this in the Standard:
On exit from a scope (however accomplished), destructors (12.4) are called for all constructed objects with automatic storage duration (3.7.2) (named objects or temporaries) that are declared in that scope, in the reverse order of their declaration.
So it seems that destructors must be called on receipt of a signal.
Solution 3:
Another case they won't be called is if you are using polymorphism and have not made your base destructors virtual.