What is the ideal usage of std::nothrow
?
I'd use it only as an optimization (or code simplification) when I would otherwise have put a try-catch block immediately around a use of regular new, catching std::bad_alloc
.
This is quite a rare situation, because it's rare to be able to usefully handle out-of-memory right there at the call site. Usually you allocate memory because you need it, not because you'd quite like to have it but can live without. Code that passes null pointers back up a chain of callers until eventually someone can deal with the problem isn't idiomatic C++.
It can happen though that the error genuinely can be handled immediately. For example you might be in a situation where you'll use one algorithm or technique given sufficient working space, and a different, slower algorithm or technique without. Then again, would you be allocating such working space directly with new
? Not normally. And anyway, you sometimes have to be careful with that approach, because if your OS overcommits then in general you cannot handle out of memory gracefully at the application level.
Note that an expression involving std::nothrow can still throw an exception (in particular from any constructor of the object being allocated), so it's only one thing needed if you're hoping to avoid throwing an exception. You also have to ensure that the constructor won't throw.
As far as I'm concerned the days of C++ programs that don't use exceptions at all, are over. I suppose if they resumed for me, due to some particular style guide, then that's the other likely reason for needing nothrow new.
Porting a C program to C++. Your C program has all those checks in there, after every malloc, and no notion of exceptions. So it's much simpler to change every malloc to new (nothrow) than to wrap every malloc in a try block.
malloc
? Even in C++, malloc
does not throw. –
Abutment malloc
and free
work together? If not it might be simplest to convert so that you can be consistent. –
Evocator malloc
s memory and leaves it to the caller to free
, then clients of the C++ version might prefer to delete
instead, but by changing the interface in that way you have to make changes to any C++ code that was already using the old C version. I suppose I could agree with the change for that reason, assuming no such existing C++ code. Unpleasant interface, though, there are likely better ways to improve it for the C++ version. –
Abutment malloc
and free
not to work together? §20.4.6 pretty much they have to... –
Interdisciplinary malloc
with delete
, not malloc
with free
. –
Evocator malloc
and delete
don't work together. –
Abutment Perhaps if your application required nano-optimization and could not allow the overhead of exception handling, then maybe nothrow
would be needed.
Bear in mind that Stroustrup is pretty adamant that the programmer can turn off overhead in C++. (As a caveat though, just because you have the choice doesn't mean you should.)
You use std::nothrow when you want to have to check for null after every new. A lot of legacy code needed it when the first version of the standard was made. A lot of legacy code written afterward use it too because people where paranoid of exceptions. Occasionally you'll run into someone that still is.
It's so very rare that you'd actually want to do this that it even took me a second to remember WTF you were talking about.
I know that there were older versions of C++ (specifically Microsoft's) which did not throw when they could not allocate the memory, but returned NULL instead. This would be an easy way of maintaining compatibility with old code rather than changing all the logic.
http://www.cplusplus.com/reference/std/new/nothrow/
This construction is rarely used, because I suspect that it doesn't really affect the memory allocation performance, rather can be used for convenience.
Still, I the generic variant is usually preferred.
I can imagine this can be used as a fast-path optimization with custom allocators - say, fail current request and grow the pool at some later/idle time. Pretty much a corner case.
Only very few programs should ever allocate more than 1 GiB of memory, and since modern systems overcommit memory, new
will never return null or throw on these systems. Therefore, there is absolutely no point in checking the return value of new/malloc at all. Just keep your memory footprint down and let the out-of-memory-killer shoot down other processes!
© 2022 - 2024 — McMap. All rights reserved.