何时应该使用std::nothrow?

34

什么情况下最合适使用std::nothrow

9个回答

12

我只会在需要立即捕获std::bad_alloc时,将其用作优化(或代码简化)。这种情况相当罕见,因为通常情况下,能够有用地处理内存不足的位置都不在调用点,而是在更高层次的代码中。通过将空指针传回到调用链中直到某个人可以处理问题的代码并不是 C++ 的惯用写法。

但也有可能在此处确实可以立即处理错误。例如,您可能处于这样的情况:如果有足够的工作空间,您将使用一种算法或技术,否则您将使用不同的、较慢的算法或技术。然而,您会直接使用new来分配这样的工作空间吗?通常情况下不会。而且,您有时必须小心这种方法,因为如果您的操作系统过度承诺,那么通常情况下您无法在应用程序级别上优雅地处理内存不足问题。

请注意,涉及std::nothrow的表达式仍然可能抛出异常(特别是从正在分配对象的任何构造函数中),因此,如果您希望避免抛出异常,只有一个 thing 是不够的。您还必须确保构造函数不会抛出异常。

就我而言,不再有不使用异常的C++程序。我想,如果它们恢复了,可能是由于某种特定的样式指南,那么这也是需要 nothrow new 的另一个可能原因。


这个答案与问题有什么关系?问题是关于std::nothrow,而不是关于不抛出异常的方法。 - kingston
就我而言,不使用异常的C++程序的时代已经结束了。 欢迎来到游戏开发。 - Tara

9
据我了解,基本上从来没有和没有。

9

将C程序移植到C ++。您的C程序在每个malloc之后都有所有这些检查,而且没有异常的概念。因此,将每个malloc更改为new(nothrow)要比将每个malloc包装在try块中简单得多。


15
把它们留在malloc里不是更简单吗?即使在C++中,malloc也不会抛出异常。 - Steve Jessop
@Steve Jessop,mallocfree能够保证配合使用吗?如果不能,最简单的方法可能是进行转换,以便您可以保持一致性。 - Mark Ransom
4
@Mark:不确定你所说的“一起工作”是什么意思。如果C代码没有释放它分配的所有内容,则修复错误与移植代码是两件不同的事情。如果C库使用malloc函数分配内存并将其留给调用者进行free,那么C++版本的客户端可能更喜欢单纯地使用delete,但是通过这种方式更改接口,您必须对已经使用旧C版本的任何C++代码进行更改。我认为如果不存在这样的现有C++代码,出于这个原因我可能会同意进行更改。然而,这种接口不太友好,改进C++版本的方法可能会更好。 - Steve Jessop
@Mark:有没有可能mallocfree不能一起使用的情况?根据§20.4.6,它们几乎必须一起使用。 - conio
2
@conio,感谢提供参考。当然我是指用delete来代替malloc,而不是用free - Mark Ransom
@Mark:如果担心意外混用,那么某人(可能是开发人员,如果不是,则是测试人员)应该使用调试内存分配器,它提供了一个保证mallocdelete不会一起工作的保证。 - Steve Jessop

5
也许,如果您的应用程序需要纳米优化,并且不能允许异常处理的开销,则可能需要使用 nothrow
请记住,Stroustrup非常坚定地认为程序员可以在C++中关闭开销。(尽管有一个警告,仅因为您有选择并不意味着您应该这样做。)

4
你在每次使用new之后想要检查是否为空时可以使用std::nothrow。很多旧代码在标准的第一个版本中需要它。之后编写的很多旧代码也使用它,因为人们对异常非常谨慎。偶尔你会遇到仍在使用它的人。
实际上,你需要这样做的情况非常罕见,以至于我甚至花了一秒钟才记起你在说什么。

3

我知道旧版本的C++(特别是微软的)在无法分配内存时不会抛出异常,而是返回NULL。这是一种与旧代码兼容的简单方法,而不是改变所有逻辑。


3
据我所知,这不是微软的问题,而只是在引入异常之前,在标准 C++ 之前的新工作方式。 - Yakov Galka
Tizen OS不支持标准的异常处理。他们使用nothrow和两阶段构造函数。 - bikram990

1

1

我可以想象这可以作为使用自定义分配器的快速路径优化 - 比如,在某个稍后/空闲时间失败当前请求并增加池。这几乎是一个边角情况。


-2
只有极少数的程序应该分配超过1 GiB的内存,由于现代系统会过度承诺内存,所以在这些系统上,new永远不会返回null或抛出异常。因此,根本没有必要检查new/malloc的返回值。只需保持内存占用率较低,并让内存不足终结者关闭其他进程!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接