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

时间:2010-11-04 08:45:10

标签: 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;
}

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

3 个答案:

答案 0 :(得分:16)

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

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

答案 1 :(得分: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)
  • 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 ~ $ 
    

    答案 2 :(得分:4)

      

    $ 15.2 / 2 - “部分对象   建造或部分毁坏   将为所有人执行析构函数   其完全构建的基类   和非变体成员,即   主体的子对象   构造函数(12.6.2)已完成   执行和析构函数没有   尚未开始执行。同样,如果   非委托构造函数   对象已完成执行并且已完成   委托该对象的构造函数   退出异常,对象的   析构函数将被调用。 如果   对象分配在一个   new-expression,匹配   解除分配函数(3.7.4.2,5.3.4,   12.5),如果有的话,调用以释放对象占用的存储空间。