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