Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid std::bad_alloc. new should return a NULL pointer

I port a middle-sized application from C to C++. It doesn't deal anywhere with exceptions, and that shouldn't change.

My (wrong!) understanding of C++ was (until I learned it the hard way yesterday) that the (default) new operator returns a NULL pointer in case of an allocation problem. However, that was only true until 1993 (or so). Nowadays, it throws a std::bad_alloc exception.

Is it possible to return to the old behavior without rewriting everything to using std::nothrow on every single call?

like image 360
dmeister Avatar asked Nov 10 '09 09:11

dmeister


4 Answers

You could overload operator new:

#include <vector>

void *operator new(size_t pAmount) // throw (std::bad_alloc)
{
    // just forward to the default no-throwing version.
    return ::operator new(pAmount, std::nothrow);
}

int main(void)
{
    typedef std::vector<int> container;

    container v;
    v.reserve(v.max_size()); // should fail
}
like image 77
GManNickG Avatar answered Nov 14 '22 17:11

GManNickG


Include the header <new>. It contains a "no-throw" version of new you can use like this:

#include <new>

int main() {
    int* p = new(std::nothrow) int;
    if (p) {
        delete p;
    }
}

Edit: I admit I missed the last sentence of the question. But to be honest, I think that tweaking "plain new" to have pre-Standard behaviour isn't a good idea either. I'd look into some kind of automated search & replace to turn each new into new(std::nothrow).

like image 43
sellibitze Avatar answered Nov 14 '22 18:11

sellibitze


Sorry, but as for my opinion you should NOT do this and return to old new behavior. This is because you simply can't avoid exceptions anyway.

WHY?

Consider about new call which should allocate class with constructor calling some initialization code which needs to construct anything temporary which is dynamic. Alas, you are going to have exception. No matter if you use std::nothrow. This is only one scenario among number of them.

In Scott Meyers book Effective C++ it was discussed in details as far as I remember. But I'm not sure if all the cases are reviewed (but I suggest enough of them).

like image 1
Roman Nikitchenko Avatar answered Nov 14 '22 18:11

Roman Nikitchenko


Just try it out :

1.Define a function which you want to invoke on out of memory condition.

2.Pass this function to set_ new _handler function so when new fails this function will be called.

like image 1
Ashish Avatar answered Nov 14 '22 18:11

Ashish