I know that according to C++ standard in case the new fails to allocate memory it is supposed to throw std::bad_alloc exception. But I have heard that some compilers such as VC6 (or CRT implementation?) do not adhere to it. Is this true ? I am asking this because checking for NULL after each and every new statement makes code look very ugly.
相关问题
- Sorting 3 numbers without branching [closed]
- How to compile C++ code in GDB?
- Why does const allow implicit conversion of refere
- thread_local variables initialization
- What uses more memory in c++? An 2 ints or 2 funct
相关文章
- Class layout in C++: Why are members sometimes ord
- How to mock methods return object with deleted cop
- Which is the best way to multiply a large and spar
- C++ default constructor does not initialize pointe
- Selecting only the first few characters in a strin
- What exactly do pointers store? (C++)
- Converting glm::lookat matrix to quaternion and ba
- What is the correct way to declare and use a FILE
Based on the C++ spec, it will always throw std::bad_alloc when you use just plain new with no params, but of course there can be some non compliant compilers.
I would not code to be compliant with non c++ compliant compilers though. VC6 being one of them in this respect.
It is good practice though to always set your pointer to NULL after you delete them. So because of that, checking for NULL is still needed.
That being said, here are a couple options to cleaning up your code:
Option 1: Setting your own new handler
A safe way to clean up your code would be to call: set_new_handler first.
Then you could check for NULL in your handler and throw std::bad_alloc there if NULL is returned.
If you like exceptions better, then this is your best bet. If you like to return NULL better then you can also do that by doing a catch inside your new handler.
Option 2: Using overloaded new
The c++ standard header file defines a struct nothrow which is empty. You can use an object of this struct inside new to get its overloaded version that always returns NULL.
So in your code:
Here is a good refrence for further reading
I'd like to add the (somewhat controversial) opinion that checking for NULL after an allocation attempt is pretty much an exercise in futility. If your program ever runs into that situation, chances are you can't do much more than exiting fast. It's very likely that any subsequent allocation attempt will also fail.
Without checking for NULL, your subsequent code would attempt to dereference a NULL pointer, which tends to exit the program fast, with a relatively unique (and easily debuggable) exit condition.
I'm not trying to talk you out of checking for NULL, it's certainly conscientious programming. But you don't gain much from it, unless in very specific cases where you can perhaps store some recovery information (without allocating more memory), or free less important memory, etc. But those cases will be relatively rare for most people.
Given this, I'd just trust the compiler to throw bad_alloc, personally - at least in most cases.
VC6 was non-compliant by default in this regard. VC6's
new
returned0
(orNULL
).Here's Microsoft's KB Article on this issue along with their suggested workaround using a custom
new
handler:If you have old code that was written for VC6 behavior, you can get that same behavior with newer MSVC compilers (something like 7.0 and later) by linking in a object file named
nothrownew.obj
. There's actually a fairly complicated set of rules in the 7.0 and 7.1 compilers (VS2002 and VS2003) to determine whether they defaulted to non-throwing or throwingnew
.It seems that MS cleaned this up in 8.0 (VS2005)—now it always defaults to a throwing new unless you specifically link to
nothrownew.obj
.Note that you can specify that you want
new
to return0
instead of throwingstd::bad_alloc
using thestd::nothrow
parameter:This appears to work in VC6, so it could be a way to more or less mechanically fix the code to work the same with all compilers so you don't have to rework existing error handling.