简体   繁体   中英

What happens to the memory allocated by `new` if the constructor throws?

Will this code cause a memory leak?

#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;
}

The memory allocated by new is never deleted. Is this taken care of internally, or it an actual memory leak?

The memory will be automatically freed before the exception propagates.

This is essential, because a) the program never receives a pointer to free, and b) even if it did, it would have no portable way to actually free it since the memory never became an object that you can delete.

The memory will be properly deallocated.

Related questions at 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 ~ $ 
    

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

    The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM