在c ++类

时间:2016-09-30 21:13:19

标签: c++ memory-leaks constructor exception-handling destructor

下面的代码是否表示内存泄漏?

没有调用Test类的析构函数(屏幕上没有输出),我假设分配给Int类数组的所有内存都没有返回给系统?我的假设是否正确?如果发生异常,我应该如何声明在构造函数中分配的资源?

#include <iostream>
using namespace std;

class Int{
   public:
      int v;
      Int(){
        cout<<"inside Int constructor ..."<<endl;
      }

      ~Int(){
        cout<<"inside Int destructor ..."<<endl;
      }
};

class Test{
    public:
    Int* a;

    Test(){
        a=new Int[10];
        cout<<"inside Test constructor ..."<<endl;
        throw(0);
    }

    ~Test(){
      delete [] a;
      cout<<"inside Test destructor ..."<<endl;
    }
};

int main(){
   try{
      Test T;
   }
   catch (int e){
        cout<<"Error!!!"<<endl;
   }

    return 0;
}      

2 个答案:

答案 0 :(得分:1)

不会调用析构函数,因为该对象从未完全构造。在部分构造的对象上调用它可能更危险,因为它会尝试撤消从未完成的事情。作为程序员,在您遇到异常的情况下,确保没有内存(或任何其他资源)从构造函数中泄漏。

但是,将调用基类和成员变量的析构函数!这就是为什么在大多数情况下依靠智能指针或容器来处理资源管理的原因。试着像这样改变你的课程:

#include <memory>

class Test{
    public:
    std::unique_ptr<Int[]> a;

    Test(){
        a=std::make_unique<Int[]>(10);
        cout<<"inside Test constructor ..."<<endl;
        throw(0);
    }

    ~Test(){
      //no need to delete[] a;
      cout<<"inside Test destructor ..."<<endl;
    }
};

这是一个双赢的局面。您将看到Int的析构函数将被调用,您无需手动处理内存。

答案 1 :(得分:0)

我提出了一个解决方案,但不确定这是一个好的设计还是正确的方法。你能评论吗?

#include <iostream>
using namespace std;

class Int{
    public:
    int v;
    Int(){
        cout<<"inside Int constructor ..."<<endl;
    }

      ~Int(){
        cout<<"inside Int destructor ..."<<endl;
    }
};

class Test{
    public:
    Int* a;

    Test(){
        try{
            a=new Int[10];
            cout<<"inside Test constructor ..."<<endl;
            throw(0); // exception is thrown
           }

         catch (int e){
               delete [] a;
               cout<<"Error!!!"<<endl;
           }
        }

    ~Test(){
      delete [] a;
      cout<<"inside Test destructor ..."<<endl;
    }
};

int main(){

      Test T;


      return 0;
}