Question says it all: Are there any pitfalls with allocating exceptions on the heap?
I am asking because allocating exceptions on the heap, in combination with the polymorphic exception idiom, solve the problem of transporting exceptions between threads (for the sake of discussion, assume that I can’t use exception_ptr). Or at least I think it does…
Some of my thoughts:
- The handler of the exception will have to catch the exception and know how to delete it. This can be solved by actually throwing an
auto_ptrwith the appropriate deleter. - Are there other ways to transport exceptions across threads?
One obvious pitfall is that a heap allocation might fail.
Interestingly, when an exception is thrown it actually throws a copy of the exception object that is the argument of
throw. When using gcc, it creates that copy in the heap but with a twist. If heap allocation fails it uses a static emergency buffer instead of heap:So, one possibility is to replicate this functionality to protect from heap allocation failures of your exceptions.
Not sure if using
auto_ptr<>is a good idea. This is because copyingauto_ptr<>destroys the original, so that after catching by value as incatch(std::auto_ptr<std::exception> e)a subsequentthrow;with no argument to re-throw the original exception may throw aNULLauto_ptr<>because it was copied from (I didn’t try that).I would probably throw a plain pointer for this reason, like
throw new my_exception(...)and catch it by value and manuallydeleteit. Because manual memory management leaves a way to leak memory I would create a small library for transporting exceptions between threads and put such low level code in there, so that the rest of the code doesn’t have to be concerned with memory management issues.Another issue is that requiring a special syntax for throw, like
throw new exception(...), may be a bit too intrusive, that is, there may be existing code or third party libraries that can’t be changed that throw in a standard manner likethrow exception(...). It may be a good idea just to stick to the standard throw syntax and catch all possible exception types (which must be known in advance, and as a fall-back just slice the exception and only copy a base class sub-object) in a top-level thread catch block, copy that exception and re-throw the copy in the other thread (probably onjoinor in the function that extracts the other’s thread result, although the thread that throws may be stand-alone and yield no result at all, but that is a completely another issue and we assume we deal with some kind of worker thread with limited lifetime). This way the exception handler in the other thread can catch the exception in a standard way by reference or by value without having to deal with the heap. I would probably choose this path.You may also take a look at Boost: Transporting of Exceptions Between Threads.