开发者

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

开发者 https://www.devze.com 2022-12-10 20:04 出处:网络
I port a middle-sized application from C to C++. It doesn\'t deal anywhere with exceptions, and that shouldn\'t change.

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 learn开发者_开发百科ed 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?


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
}


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).


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).


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.


Your compiler likely has a commandline switch to enable/disable this behaviour.

0

精彩评论

暂无评论...
验证码 换一张
取 消