dmeister
dmeister

Reputation: 35634

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?

Upvotes: 6

Views: 4855

Answers (5)

Ashish
Ashish

Reputation: 8529

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.

Upvotes: 1

sellibitze
sellibitze

Reputation: 28107

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

Upvotes: 4

Roman Nikitchenko
Roman Nikitchenko

Reputation: 13046

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

Upvotes: 1

GManNickG
GManNickG

Reputation: 504073

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
}

Upvotes: 13

Will
Will

Reputation: 75665

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

Upvotes: 0

Related Questions