2010-08-15 61 views
5

我有一个关于内存释放和异常的问题。当我使用删除来删除在堆上创建的对象时。如果在删除之前发生异常,内存泄漏或将执行此删除操作?内存释放和异常

+0

你的意思是之前,而不是?那么这很明显,如果'delete'不会被调用(因为之前抛出异常),那么不会释放内存。如果您在销毁期间询问异常,请http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.3 – adf88 2010-08-15 09:09:26

回答

3

这取决于delete的位置。如果它在捕获异常的catch内,则可能会调用它。

try { 
    f(); // throws 
} catch(...) { 
    delete p; // will delete 
} 

如果它是捕捉异常的catch后和catch不从函数返回(即允许执行流程的catch块之后进行),那么delete可能会被调用。

try { 
    f(); // throws 
} catch(...) { 
    // execution proceeds beyond catch 
} 
delete p; // will delete 

如果delete不处于catch块或catch块,其允许执行继续进行,则delete不会调用之后。

try { 
    f(); // throws 
} catch(...) { 
    g(); // throws 
    delete p; // will not delete 
} 
+1

请注意,异常情况良好,因为您不必每次都捕获它们函数在调用堆栈中。它们可以在一个“外部”层面上连接。你如何释放内部函数中分配的内存?例如,如果函数f()抛出一个异常分配内存。在f()和空闲内存中捕获异常,然后在调用堆栈中将其重新抛入下一级,会不会是一个好主意? – NickSoft 2013-03-14 08:51:04

2

它不会被调用。这就是为什么你被鼓励去看RAII的原因。请参阅Stroustrup

5

在您描述的情况下,内存将泄漏。

两个技巧来避免这个问题:

  • 使用智能指针,不从相同的问题的困扰(优选溶液)
    - >在堆栈上构造的智能指针,其因此,调用析构函数,不管是什么,并在析构函数提供

  • 使用try/catch语句所指向的内容删除,并在catch语句删除的项目以及

0

我们还必须确保“异常”:

try { 
    f(); // throws 
    delete p; // will not delete 
} // ... 

正如你可以想像,在两个第一例delete上面不会,如果有是delete前一抛调用真的意味着可以被try/catch捕获的C++异常。在C++ try/catch无法捕捉的系统中也存在其他异常(例如,除以0)。在这种情况下(超出C++标准的范围),除非这些异常被捕获并且处理程序明确地调用“delete”,否则“delete”将不会被执行。