2017-01-19 41 views
1

当使用new并引发bad_alloc异常时。在继续之前,你还需要在ptr上调用delete吗?还是可以确信没有分配内存?关于new的错误分配错误,还需要调用delete吗?

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

+0

你在说什么“ptr”?发布一些代码。 –

+0

任何正在通过新的 –

+0

后分配内存的ptr。一些。码。问题的第一部分是书面的无法回答的,边缘的荒谬。当“新”抛出时,表达式评估没有完成。 –

回答

2

当一个异常被抛出,你不“矣” - 执行跳转到catch处理。

在像的表达式:

p = new int; 

子表达式new int首先计算。如果抛出一个异常,那么执行没有达到分配。 p保留之前的值(如果有的话)。

p = new(std::nothrow) int;的情况下,如果分配失败,p将变为空指针。在空指针上调用delete不起作用。

+0

没有它没有。你回答了。我问你是否可以确信没有任何分配和/或没有分配内存。 –

2

new的抛出异常的版本确实通过返回一个空指针,在这种情况下,没有内存的分配报告错误和没有对象已建成:

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函数模板来封装这最后一点。)

+1

当然,第二个例子有内存泄漏的问题,如果// stuff可以抛出 –

+0

@ M.M:第一个例子也有这个问题。我假设你通常知道需要异常正确的代码。 –

+1

是的,我认为如果你的回答在某个阶段提到这将是一件好事,因为初学者并不清楚最后一个版本的优点是什么 –