2010-11-04 56 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)(如果有),以释放该对象占用的存储空间。

    相关问题