【问题标题】:What happens to the memory allocated by `new` if the constructor throws?如果构造函数抛出,由`new`分配的内存会发生什么?
【发布时间】:2010-11-04 08:45:09
【问题描述】:

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

#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 分配的内存永远不会被删除。这是内部处理的,还是实际的内存泄漏?

【问题讨论】:

    标签: c++


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      内存将被正确释放。

      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 ~ $ 
      

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-04-03
          • 2014-04-03
          • 2011-05-20
          • 2012-08-08
          • 2012-05-10
          • 2019-06-17
          相关资源
          最近更新 更多