I have this code..
CEngineLayer::CEngineLayer(void) { // Incoming creation of layers. Wrapping all of this in a try/catch block is // not helpful if logging of errors will happen. logger = new (std::nothrow) CLogger(this); if(logger == 0) { std::bad_alloc exception; throw exception; } videoLayer = new (std::nothrow) CVideoLayer(this); if(videoLayer == 0) { logger->log("Unable to create the video layer!"); std::bad_alloc exception; throw exception; } } IEngineLayer* createEngineLayer(void) { // Using std::nothrow would be a bad idea here as catching things thrown // from the constructor is needed. try { CEngineLayer* newLayer = new CEngineLayer; return (IEngineLayer*)newLayer; } catch(std::bad_alloc& exception) { // Couldn't allocate enough memory for the engine layer. return 0; } }
I've omitted most of the non-related information, but I think the picture is clear here.
Is it okay to manually throw an std::bad_alloc instead of try/catching all of the layer creations individually and logging before rethrowing bad_allocs?
std::bad_alloc is a type of exception that occurs when the new operator fails to allocate the requested space. This type of exception is thrown by the standard definitions of operator new (declaring a variable) and operator new[] (declaring an array) when they fail to allocate the requested storage space.
std::bad_alloc is the type of the object thrown as exceptions by the allocation functions to report failure to allocate storage.
bad_alloc in C++ Standard C++ contains several built-in exception classes. The most commonly used is bad_alloc, which is thrown if an error occurs when attempting to allocate memory with new. This class is derived from exception.
Just to answer the question (since nobody else seems to have answered it), the C++03 standard defines std::bad_alloc
as follows:
namespace std { class bad_alloc : public exception { public: bad_alloc() throw(); bad_alloc(const bad_alloc&) throw(); bad_alloc& operator=(const bad_alloc&) throw(); virtual ˜bad_alloc() throw(); virtual const char* what() const throw(); }; }
Since the standard defines a public constructor, you'd be perfectly safe to construct and throw one from your code. (Any object with a public copy constructor can be thrown, IIRC).
You don't need to do that. You can use the parameterless form of the throw
statement to catch the std::bad_alloc
exception, log it, then rethrow it:
logger = new CLogger(this); try { videoLayer = new CVideoLayer(this); } catch (std::bad_alloc&) { logger->log("Not enough memory to create the video layer."); throw; }
Or, if logger
is not a smart pointer (which it should be):
logger = new CLogger(this); try { videoLayer = new CVideoLayer(this); } catch (std::bad_alloc&) { logger->log("Not enough memory to create the video layer."); delete logger; throw; } catch (...) { delete logger; throw; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With