的理想用法是std::nothrow
什么?
9 回答
我只会将它用作优化(或代码简化),否则我会在使用常规 new, catch 时立即放置一个 try-catch 块std::bad_alloc
。
这是一种非常罕见的情况,因为很少能够在调用站点有效地处理内存不足。通常你分配内存是因为你需要它,而不是因为你很想拥有它但可以没有它。将空指针传递回调用者链直到最终有人可以处理该问题的代码不是惯用的 C++。
尽管确实可以立即处理错误,但也可能发生这种情况。例如,您可能会在有足够工作空间的情况下使用一种算法或技术,而没有使用另一种较慢的算法或技术。再说一次,你会直接分配这样的工作空间new
吗?不正常。无论如何,您有时必须小心使用这种方法,因为如果您的操作系统过度使用,那么通常您无法在应用程序级别优雅地处理内存不足。
请注意,涉及 std::nothrow 的表达式仍然可以引发异常(特别是从正在分配的对象的任何构造函数),因此如果您希望避免引发异常,则只需要一件事。您还必须确保构造函数不会抛出。
就我而言,完全不使用异常的 C++ 程序的时代已经结束。我想如果他们为我恢复,由于一些特定的风格指南,那么这就是需要 nothrow new 的另一个可能的原因。
据我了解,几乎从来没有,也没有。
将 C 程序移植到 C++。你的 C 程序在每个 malloc 之后都有所有这些检查,并且没有异常的概念。因此,将每个 malloc 更改为 new (nothrow) 比将每个 malloc 包装在 try 块中要简单得多。
也许如果您的应用程序需要纳米优化并且不允许异常处理的开销,那么可能nothrow
需要。
请记住,Stroustrup 非常坚持程序员可以关闭 C++ 中的开销。(但需要注意的是,仅仅因为您有选择权并不意味着您应该这样做。)
当您希望在每次新建后都必须检查 null 时,您可以使用 std::nothrow。在制定标准的第一个版本时,许多遗留代码都需要它。许多后来编写的遗留代码也使用它,因为人们偏执于异常。偶尔你会遇到一个仍然是的人。
你真的想这样做是非常罕见的,我什至花了一秒钟才想起你说的 WTF。
我知道有旧版本的 C++(特别是微软的)在无法分配内存时没有抛出,而是返回 NULL。这将是保持与旧代码兼容性而不是更改所有逻辑的简单方法。
我可以想象这可以用作自定义分配器的快速路径优化 - 例如,当前请求失败并在稍后/空闲时间增加池。几乎是一个角落案例。
http://www.cplusplus.com/reference/std/new/nothrow/
这种结构很少使用,因为我怀疑它并没有真正影响内存分配性能,而是为了方便使用。
不过,我通常首选通用变体。
只有极少数程序应该分配超过 1 GiB 的内存,并且由于现代系统过度使用内存,new
因此永远不会返回 null 或在这些系统上抛出异常。因此,检查 new/malloc 的返回值是完全没有意义的。只要保持你的内存占用,让内存不足的杀手击落其他进程!