std::bad_alloc

Exceptions are one of the most flamed topics in C++. But before I talk about the operator new I want to say a few things in general about them. There are many ways to use exceptions, different approaches. Although, it costs more than error checking in sake of speed, it is pretty convenient and usable. Well, some people use it to replace these return code tests. Others use it in rare cases where something less expected happens. I even saw some justified reasons to why not use it. For instance, you can’t see if a function throws an exception from merely looking at its interface. Every library has its own type of exception base class, CAtlException, std::exception, etc… And you should not let anything slip your catch clause. So sometimes it might be pretty annoying to catch them all, and then you have to multiple your inside-catch-clause-code for handling each different exception. And if you have C++, you won’t dare using goto, even not for a cleanup…Of course, there are good sides also and that’s why most people use them after all.

If we take a look at the operator new, that’s the C++ raw memory allocator, we will see that it might throw an std::bad_alloc in case of failure, which is 100% legitimate, because most of the times you just expect that it will return your a pointer to a valid contigious block of memory. But now, assuming I use my own internal exceptions type for my application; Why do I need everytime to catch this exception and rethrow the converted exception? This is waste of time both in development and in run time. And there are some approaches who believe you don’t have to catch it at all, because if it is thrown, you are dead anyways. Now tell me seriously, if you write a real software for a company, you are not going to catch it? now gimme a break! So catching it you must, and therefore I don’t think every usage of the new operator should be wrapped by its own try and catch if you wrap it anyways with catching your own application’s exception. So eventually, after lots of discussions with my colleagues, we decided it suits us mostly to overload the global operator new function with our own custom function with a single change, that it will throw our exception rather than std::bad_alloc in case of failure. Overloading that operator, requires you to overload the array interface also. Don’t forget, when overloading new you will want to overload delete… :)

4 Responses to “std::bad_alloc”

  1. Erez says:

    You should note that there is the option that new that won’t throw an exception. I think it goes like “new(std::no_throw) …”, and it behaves pretty much like malloc.
    I mean, if you’re going to wrap new, then there’s no real point of having it throw an exception, right?

  2. arkon says:

    No, I was saying that I wrap the code with MY own application’s exceptions. So instead of wrapping again and catching bad_alloc, I prefer to throw my own type of exceptions that would be caught anyways. And I believe that if you use exceptions like the operator new does, you should expect a valid pointer always, otherwise an exception will be thrown. So it spares you the tests for null.

  3. jack says:

    Why don’t you just catch the bad_alloc exception in the same try/catch block that handles your app’s exceptions? Like this:

    catch (myException &e) {
    //handle my exception
    } catch (std::bad_alloc &e) {
    //handle out of memory
    }

  4. Frederik says:

    Why even bother overloading new, and not just inherit _all_ your own exceptions from std::exception? Are there any good reasons for not doing so? There are certainly plenty of good reasons for inheriting std::exception — first of all it allows you to have one huge try block that catches all exceptions but still allows you to set some standards for them, and it makes sure that if everybody does so, you will catch all exceptions — the alternative seems to be to treat everything else as a terminal error.

Leave a Reply