Can the C++ `new` operator ever throw an exception

2019-03-08 09:45发布

Can the new operator throw an exception in real life?

And if so, do I have any options for handling such an exception apart from killing my application?

Update:

Do any real-world, new-heavy applications check for failure and recover when there is no memory?


See also:

18条回答
爷的心禁止访问
2楼-- · 2019-03-08 10:16

Most realistically new will throw due to a decision to limit a resource. Say this class (which may be memory intensive) takes memory out of the physicals pool and if to many objects take from it (we need memory for other things like sound, textures etc) it may throw instead of crashing later on when something that should be able to allocate memory takes it. (looks like a weird side effect).

Overloading new can be useful in devices with restricted memory. Such as handhelds or on consoles when its too easy to go overboard with cool effects.

查看更多
姐就是有狂的资本
3楼-- · 2019-03-08 10:17

new operator will throw std::bad_alloc exception when you run out of the memory ( virtual memory to be precise).

If new throws an exception then it is a serious error:

  • More than available VM is getting allocated ( it fails eventually). You can try reducing the amount of memory than exiting the program by catching std::bad_alloc exception.
查看更多
做个烂人
4楼-- · 2019-03-08 10:19

In Unix systems, it's customary to run long-running processes with memory limits (using ulimit) so that it doesn't eat up all of a system's memory. If your program hits that limit, you will get std::bad_alloc.


Update for OP's edit: the most typical case of programs recovering from an out-of-memory condition is in garbage-collected systems, which then performs a GC and continues. Though, this sort of on-demand GC is really for last-ditch efforts only; usually, good programs try to GC periodically to reduce stress on the collector.

It's less usual for non-GC programs to recover from out-of-memory issues, but for Internet-facing servers, one way to recover is to simply reject the request that's causing the memory to run out with a "temporary" error. ("First in, first served" strategy.)

查看更多
▲ chillily
5楼-- · 2019-03-08 10:23

Yes, new can and will throw if allocation fails. This can happen if you run out of memory or you try to allocate a block of memory too large.

You can catch the std::bad_alloc exception and handle it appropriately. Sometimes this makes sense, other times (read: most of the time) it doesn't. If, for example, you were trying to allocate a huge buffer but could work with less space, you could try allocating successively smaller blocks.

查看更多
我想做一个坏孩纸
6楼-- · 2019-03-08 10:27

It's good to check/catch this exception when you are allocating memory based from something given from outside (from user space, network e.g.), because it could mean an attempt to compromise your application/service/system and you shouldn't allow this to happen.

查看更多
何必那么认真
7楼-- · 2019-03-08 10:28

The new operator, and new[] operator should throw std::bad_alloc, but this is not always the case as the behavior can be sometimes overridden.

One can use std::set_new_handler and suddenly something entirely different can happen than throwing std::bad_alloc. Although the standard requires that the user either make memory available, abort, or throw std::bad_alloc. But of course this may not be the case.

Disclaimer: I am not suggesting to do this.

查看更多
登录 后发表回答