Search code examples
c++new-operatorthrowbad-alloc

Is it okay to manually throw an std::bad_alloc?


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?


Solution

  • 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;
    }