在 new 的 bad allocation 错误上,是否还需要调用 delete?

On new's bad allocation error, does delete still need to be called?

使用 new 时抛出 bad_alloc 异常。在继续之前,您是否仍然需要在 ptr 上调用 delete,或者您可以确信没有分配内存吗?

如果你使用nothrow版本呢?如果返回 nullptr,你能再次确信没有分配内存吗?

new的nothrow版本确实通过返回一个空指针来报告错误,在这种情况下没有分配内存也没有构造对象:

T * p = new (std::nothrow) T(a, b, c);

if (p)
{
    // stuff
}

delete p;   // OK, works on null pointers, too.

或者也许:

if (T * p = new (std::nothrow) T(a, b, c))
{
    // stuff
    delete p;
}
else
{
    // allocation failure
}

甚至更好:

if (std::unique_ptr<T> p(new (std::nothrow) T(a, b, c)))
{
    // stuff
}

最后一个版本在 if 块的任何出口处自动删除动态对象,这是 C++ 处理多个出口的方式的典型示例,从而将复杂性本地化。

(也许应该有一个make_unique_or_null函数模板来封装最后一点。)

抛出异常时,您不会 "carry on" - 执行跳转到 catch 处理程序。

在这样的表达式中:

p = new int;

sub-expression new int 首先被评估。如果抛出异常,则执行不会到达分配。 p 保留它以前的值(如果有的话)。

p = new(std::nothrow) int;的情况下,如果分配失败,p将成为一个空指针。在空指针上调用 delete 无效。