创建类变量时的内存泄漏

时间:2015-11-11 12:27:17

标签: c++ memory-leaks operator-overloading

使用operator overloading memory leak的答案 我添加了复制构造函数和复制assingment运算符,更改了运算符+(),因为NathanOliver建议,现在我传递给构造函数静态数组。还有内存泄漏和奇怪的事情是我得到这个内存泄漏,即使在主要只有类变量初始化,无论是否与参数有关...任何建议?我认为cunstructor是有效的。

Set::Set(int n, int* array){
   number = n; 
   elems = array;
   std::sort(elems, elems + number);
}

Set::Set(const Set& s){
   number=s.number;
   elems=s.elems;
}
Set& operator=(const Set& X){

   if(this==&X)
     return *this;
   delete [] elems;
   elems=X.elems;
   number=X.number;
   return *this;

我使用gcc(tdm64-2)4.8.1编译器。

1 个答案:

答案 0 :(得分:4)

c ++中有两种副本,浅拷贝和深拷贝。第一个只复制指针,后一个复制值。默认情况下,复制构造函数和重载赋值运算符如果由编译器生成则执行浅复制。现在让我们来看看你的代码。

Set::Set(int n, int* array){
   number = n; 
   elems = array;
   std::sort(elems, elems + number);
}

此构造函数采用in数组。如果使用new在堆上分配此数组,则应使用delete []解除分配。现在声明:

 elems = array;

是浅拷贝,它实际上复制指针而不是值。因此,如果您不小心删除了main中的数组,那么elem将成为一个悬空指针,因为它将指向一个已删除的数组。在此之后取消引用或删除elem将具有未定义的行为。

现在同样适用于此:

Set& operator=(const Set& X){

   if(this==&X)
   return *this;
   delete [] elems;
   elems=X.elems;
   number=X.number;
   return *this;
}

你再次制作浅拷贝,你只需要复制指针。为了解决这个问题,你需要

delete[] elems;
elems = new int[n]; //where n is x.elems length
//use memcpy() function or a for loop to copy the values of x.elems

最后在你的类中添加一个类析构函数:

~Set() {
     if(elems != nullptr) //check for empty array
         delete[] elems;
 }

请记住bjarne stroustrup c ++的创建者说你应该遵循RIII(称为R tripple i)。基本上,当你创建一个类时总是在构造函数中使用new并在析构函数中删除。避免在任何其他功能中使用new / delete。传递指针可能很棘手。