【问题标题】:Why new std::nothrow version is not widely used [duplicate]为什么新的 std::nothrow 版本没有被广泛使用[重复]
【发布时间】:2013-08-06 08:58:11
【问题描述】:

根据C++ reference,您可以通过以下方式新建对象:

MyClass * p1 = new MyClass;

或通过

MyClass * p2 = new (std::nothrow) MyClass;

第二个将返回一个空指针而不是抛出异常。

但是,根据我的经验,我几乎看不到这个版本。

例如,Google 不建议在他们的代码中使用异常,但我可以看到他们在 Chromium 中也没有使用 nothrow 版本。

有什么理由让我们更喜欢默认的而不是 nothrow 吗?即使在不使用异常的项目中?

-- 编辑--

后续问题:我应该检查malloc()的返回值吗?

看来,恰恰相反,很多人建议检查malloc的返回值,有人说是因为:

许多分配失败与内存不足无关。碎片可能会导致分配失败,因为即使有足够的可用内存,也没有足够的连续空间可用。

这是真的吗?为什么在这种情况下我们对待malloc()new() 的方式不同?

【问题讨论】:

  • 如果 new 失败,你很可能内存不足,无论如何都需要退出......
  • 请注意,在其他语言中,例如 java - 我们区分 exceptionerror通常 致命)。在 java 中,内存不足是 error 而不是 exception
  • 除了征求意见外,您的结束问题似乎自相矛盾。根据定义,如果您使用抛出异常的版本,那么您正在使用异常,因此“即使在不使用异常的项目中”这一点也没有实际意义。如果“不使用异常”意味着您没有 try-catch-blocks,因此运行时将捕获异常并终止程序(通常)您 stll 使用异常;您只是没有在您编写的代码中处理它们。
  • 相关,对于每个人都说“你无论如何都无法恢复,所以为什么要打扰”:Is “Out Of Memory” A Recoverable Error?
  • @WhozCraig 您不一定会使用异常,因为您没有指定 std::nothrow。您也可以使用编译器开关禁用它们。

标签: c++ exception malloc new-operator


【解决方案1】:

但是,根据我的经验,我几乎看不到这个版本。

如果您可以在本地处理故障,您将使用它(或者,等效地,从默认版本中捕获异常);可能是通过请求释放一些其他内存然后重试,或者尝试分配更小的内存,或者使用不需要额外内存的替代算法。

有什么理由让我们更喜欢默认的而不是 nothrow 的?

异常的一般原则:如果你不能在本地处理它,那么在本地检查是没有意义的。与返回值不同,异常是不能被忽略的,所以不可能不顾一切地使用空指针。

即使在不使用异常的项目中?

通常,根本无法处理内存不足的情况。在这种情况下,终止程序可能是最好的回应;这是对未处理异常的默认响应。因此,即使您没有使用异常,默认的new 也可能是大多数情况下的最佳选择。

我应该检查malloc()的返回值吗?

是的:这是检查它是否成功的唯一方法。如果你不这样做,那么你最终可能会使用空指针,给出未定义的行为:通常是崩溃,但可能是数据损坏或其他奇怪的行为和长时间的调试会话(希望)找出问题所在。

为什么在这种情况下我们对待 malloc()new 的方式不同?

因为malloc 强制我们检查返回值,而new 为我们提供了较少侵入性错误处理的选项。

【讨论】:

    【解决方案2】:

    如果您使用 throwing 版本,则无需测试每个 new 调用的结果以查看它是成功还是失败。通常在许多/大多数应用程序中,如果您的分配失败,您将无能为力,只能退出/中止,如果您没有明确地尝试/捕获,异常会自动为您执行。

    如果您使用nothrow 版本,您可能最终会在您的应用程序中传播一个空指针,并且稍后在与内存分配完全无关的地方崩溃/退出,从而使调试变得更加困难。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-21
      • 1970-01-01
      • 2011-06-15
      • 2014-07-30
      • 1970-01-01
      • 2015-09-13
      相关资源
      最近更新 更多