如果构造函数抛出异常,由`new`分配的内存会发生什么?

22

这段代码会导致内存泄漏吗?

#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分配的内存从来没有被删除。这个问题是在内部处理还是实际上会存在内存泄漏?

3个回答

18

异常传播前,内存将被自动释放。

这是必要的,因为a)程序从未收到需要释放的指针,b)即使程序收到了指针,也没有可移植的方式来释放它,因为内存从未成为可以删除的对象。


13

内存将得到适当的释放。

相关问题请参考SO。

  • 在构造函数中抛出异常是否安全?
  • C++:如何处理在构造函数中可能会抛出异常的资源(FAQ 17.4)
  • prasoon@prasoon-desktop ~ $ 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)
    prasoon@prasoon-desktop ~ $ 
    

    7
    "$15.2/2 - 部分构造或部分销毁的对象将会对所有完全构造的基类和非变量成员执行析构函数,即已经执行完主要构造函数(12.6.2)却还未开始执行析构函数的子对象。同样地,如果一个对象的非委托构造函数已经执行完毕,而该对象的委托构造函数因异常而退出,则该对象的析构函数将被调用。如果该对象是在new表达式中分配的,则匹配的解分配函数(3.7.4.2, 5.3.4, 12.5),如果有的话,将被调用以释放所占用的存储空间。”

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接