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

Sta*_*ked 17 c++

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

分配的内存new永远不会被删除.这是内部处理,还是实际的内存泄漏?

Mar*_*tos 16

在异常传播之前,将自动释放内存.

这是必不可少的,因为a)程序永远不会收到指向free的指针,并且b)即使它确实如此,它也没有可移植的方式来实际释放它,因为内存永远不会成为你可以删除的对象.


Pra*_*rav 12

内存将被正确释放.

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 ~ $ 
    
    Run Code Online (Sandbox Code Playgroud)


    Chu*_*dad 7

    $15.2/2 - “部分构造或部分销毁的对象将为其所有完全构造的基类和非变体成员执行析构函数,即,对于主构造函数(12.6.2)已完成执行的子对象并且析构函数尚未开始执行。类似地,如果对象的非委托构造函数已完成执行并且该对象的委托构造函数以异常退出,则将调用该对象的析构函数。如果该对象是在新分配的-expression,匹配的释放函数(3.7.4.2, 5.3.4, 12.5),如果有的话,会被调用来释放对象占用的存储空间。