2010-11-04 108 views
15

此代碼是否會導致內存泄漏?如果構造函數拋出`new`分配的內存會發生什麼?

#include <stdexept> 

class MyClass 
{ 
public: 
    MyClass() 
    { 
     throw std::runtime_error("Test"); 
    } 
}; 

int main() 
{ 
    try 
    { 
     MyClass * myClass = new MyClass; 
    } 
    catch (const std::exception & exc) 
    { 
     // Memory leak? 
    } 
    return 0; 
} 

new分配的內存不會被刪除。這是內部照顧,還是實際的內存泄漏?

回答

16

內存將在異常傳播之前自動釋放。

這是必不可少的,因爲a)程序永遠不會收到一個指向空閒的指針,並且b)即使它已經做到了,它也沒有可移植的方法來實際釋放它,因爲內存永遠不會成爲可刪除的對象。

12

內存將被正確釋放。在SO上的相關問題。

  • Is it ever not safe to throw an exception in a constructor?
  • C++ : handle resources if constructors may throw exceptions (Reference to FAQ 17.4)
  • [email protected] ~ $ cat noleak.cpp && g++ noleak.cpp && valgrind --leak-check=full ./a.out 
    #include <stdexcept> 
    
    class MyClass 
    { 
    public: 
        MyClass() 
        { 
         throw std::runtime_error("Test"); 
        } 
    }; 
    
    int main() 
    { 
        try 
        { 
         MyClass * myClass = new MyClass; 
        } 
        catch (const std::exception & exc) 
        { 
         // Memory leak? 
        } 
        return 0; 
    } 
    ==3652== Memcheck, a memory error detector 
    ==3652== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. 
    ==3652== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info 
    ==3652== Command: ./a.out 
    ==3652== 
    ==3652== 
    ==3652== HEAP SUMMARY: 
    ==3652==  in use at exit: 0 bytes in 0 blocks 
    ==3652== total heap usage: 3 allocs, 3 frees, 106 bytes allocated 
    ==3652== 
    ==3652== All heap blocks were freed -- no leaks are possible 
    ==3652== 
    ==3652== For counts of detected and suppressed errors, rerun with: -v 
    ==3652== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 6) 
    [email protected] ~ $ 
    
    +1

    +1對於使用Valgrind實際嘗試它。 – DarkDust 2010-11-04 08:59:40

    4

    $ 15.2/2 - 「,即部分 構造或部分被破壞的對象 將具有其完全構造基類 的所有 執行析構和非變體成員,即 子對象,其主體爲 構造函數(12.6.2)已經完成 的執行,並且析構函數還沒有開始執行 。同樣,如果 對象的非委託構造函數已完成執行,並且 委託對象 的構造函數退出且出現異常,則會調用該對象的 析構函數。 如果 對象以 新表達式分配,則會調用匹配的 解除分配函數(3.7.4.2,5.3.4, 12.5)(如果有),以釋放該對象佔用的存儲空間。

    相關問題