C++ C+中的析构函数和类+;[内存泄漏]

C++ C+中的析构函数和类+;[内存泄漏],c++,class,memory-leaks,valgrind,destructor,C++,Class,Memory Leaks,Valgrind,Destructor,我无法释放内存。首先,我要展示我的构造函数、析构函数和类的私有部分: 第1类: class VectorDinamico { private: int util, tam; int *vect; /*Rest of the class*/ } VectorDinamico::VectorDinamico() { util = 0; tam = 10; vect = new int[10]; } VectorDinamico::VectorDi

我无法释放内存。首先,我要展示我的构造函数、析构函数和类的私有部分:

第1类:

class VectorDinamico {

private:
    int util, tam;
    int *vect;

   /*Rest of the class*/
}

VectorDinamico::VectorDinamico() {
    util = 0;
    tam = 10;
    vect = new int[10];
}

VectorDinamico::VectorDinamico(const VectorDinamico &v){
    vect = new int[v.tam];

    for (int i = 0 ; i < v.util; i++) {
        vect[i] = v.vect[i];
    }
    util = v.util;
    tam = v.tam;
 }

VectorDinamico::~VectorDinamico() {
    delete []vect;
}

VectorDinamico& VectorDinamico::operator= (const VectorDinamico &v) {
    if (this != &v) {
        delete []vect;

        vect = new int[v.tam];

        for (int i = 0 ; i < v.util; i++) {
            vect[i] = v.vect[i];
        }
        util = v.util;
        tam = v.tam;
    }
    return *this;
}
class Conjunto {
private:
    VectorDinamico datos;

    /*Rest of the class*/
}

//Is empty because it uses the VectorDinamico constructor( I think )
Conjunto::Conjunto() {}

Conjunto::Conjunto( const Conjunto &c) {
   datos = c.datos; // = Is overloaded in VectorDinamico
}

//Is empty because it uses the VectorDinamico destructor( I think )
Conjunto::~Conjunto() {};

Conjunto& Conjunto::operator=( const Conjunto &c) {
    if (this != &c)
        datos = c.datos;

    return *this;
}
工作正常(Valgrind:出口处无任何使用)

第三类:(我想问题出在这里)

Setconcentos的析构函数是什么

谢谢

--------------解决了将运算符=添加到SetConcentos--------------------

我没有实现赋值操作符,因为他认为如果他没有显式地使用,就没有必要了。我错了

现在第三班是:

class SetConjuntos{
private:
    Conjunto *conjuntos;
    int util, tam;

    /*Rest of the class*/
}

SetConjuntos::SetConjuntos(){
    util = 0;
    tam = 10;
    conjuntos = new Conjunto[10];
}

SetConjuntos::SetConjuntos(const SetConjuntos &sc){
    util = sc.util;
    tam = sc.tam;
    conjuntos = new Conjunto[tam];

    for(int i = 0 ; i < util ; i++)
    conjuntos[i]=sc.conjuntos[i];
}

SetConjuntos::~SetConjuntos(){
    delete []conjuntos; //(  NO cause segmetation fault )
}

SetConjuntos& SetConjuntos::operator=(const SetConjuntos &sc){
    if(this != &sc){
        util = sc.util;
        tam = sc.tam;
        Conjunto *conjuntos_loc = new Conjunto[tam];

        for(int i = 0 ; i < util ; i++)
            conjuntos_loc[i]=sc.conjuntos[i];

        delete[] conjuntos;
        conjuntos = conjuntos_loc;
    }
    return *this;
}
setconcentos类{
私人:
康文托*康文托;
int util,tam;
/*班上其他同学*/
}
setconcentos::setconcentos(){
util=0;
tam=10;
concentos=新concento[10];
}
setconcentos::setconcentos(const setconcentos&sc){
util=sc.util;
tam=sc.tam;
concentos=新concento[tam];
for(int i=0;i
显示的代码没有明显的错误,因此错误在于您没有在问题中添加的内容

粗略猜测,您(可能是无意中)正在使用副本构造或分配,这会造成所有权问题

记住规则:要么你没有析构函数,要么你没有赋值操作符,要么你可能需要这三个


这条规则非常重要,如果您碰巧遇到一个不需要复制构造函数但需要析构函数的情况(不可能想到一个,但它可能存在),请用注释清楚地记录它,说明这不是您忘记的事情。

显示的代码没有明显的错误,因此,错误在于你没有在问题中提出的东西

粗略猜测,您(可能是无意中)正在使用副本构造或分配,这会造成所有权问题

记住规则:要么你没有析构函数,要么你没有赋值操作符,要么你可能需要这三个


此规则非常重要,如果您碰巧遇到不需要复制构造函数但需要析构函数的情况(无法想象,但它可能存在),请用注释清楚地记录它,说明这不是您忘记的事情。

SetConjutos的析构函数与您的情况一样好:

SetConjuntos::~SetConjuntos(){
    delete [] conjuntos;
}
但是,如果您有指针成员(在VectorDinamico和setconcurtos中),则需要定义复制构造函数和赋值运算符:

VectorDinamico::VectorDinamico(const VectorDinamico &v) :
    util(v.util),
    tam(v.tam),
    vect(new int[10])
{
    //copy Content of v.vect to vect
}

VectorDinamico& Operator=(const VectorDinamico &v)
{
    //Copy util, tam and the CONTENT of vec
    return *this;
}
注意:您还需要为setconcentos定义一个复制构造函数和赋值运算符

当您没有复制构造函数和赋值运算符时,可能会多次尝试释放内存


正如您在我的复制构造函数中所看到的,我正在使用一个初始值设定项列表,我也建议使用它。

SetConjutos的析构函数与您使用的一样好:

SetConjuntos::~SetConjuntos(){
    delete [] conjuntos;
}
但是,如果您有指针成员(在VectorDinamico和setconcurtos中),则需要定义复制构造函数和赋值运算符:

VectorDinamico::VectorDinamico(const VectorDinamico &v) :
    util(v.util),
    tam(v.tam),
    vect(new int[10])
{
    //copy Content of v.vect to vect
}

VectorDinamico& Operator=(const VectorDinamico &v)
{
    //Copy util, tam and the CONTENT of vec
    return *this;
}
注意:您还需要为setconcentos定义一个复制构造函数和赋值运算符

当您没有复制构造函数和赋值运算符时,可能会多次尝试释放内存


正如您在我的复制构造函数中所看到的,我正在使用一个初始值设定项列表,我也推荐使用它。

我只想向您指出,有更好的方法来编写复制赋值运算符。让我们看看你的代码:

VectorDinamico& VectorDinamico::operator= (const VectorDinamico &v) {
    if (this != &v) {
        delete []vect;
            /* What happens here is that you delete vect [ ], but what
               happens if the next line 'vect = next int [ v.tam ];' throws
               an exception?
            */
        vect = new int[v.tam];

        for (int i = 0 ; i < v.util; i++) {
            vect[i] = v.vect[i];
        }
        util = v.util;
        tam = v.tam;
    }
    return *this;
}
VectorDinamico&VectorDinamico::operator=(const VectorDinamico&v){
如果(此!=&v){
删除[]向量;
/*这里发生的是删除vect[],但是什么呢
如果下一行“vect=next int[v.tam];”抛出
例外?
*/
vect=新整数[v.tam];
for(int i=0;i

请看一看,这里您将获得如何编写副本分配运算符的详细说明。

我只想向您指出,有更好的方法来编写副本分配运算符。让我们看看你的代码:

VectorDinamico& VectorDinamico::operator= (const VectorDinamico &v) {
    if (this != &v) {
        delete []vect;
            /* What happens here is that you delete vect [ ], but what
               happens if the next line 'vect = next int [ v.tam ];' throws
               an exception?
            */
        vect = new int[v.tam];

        for (int i = 0 ; i < v.util; i++) {
            vect[i] = v.vect[i];
        }
        util = v.util;
        tam = v.tam;
    }
    return *this;
}
VectorDinamico&VectorDinamico::operator=(const VectorDinamico&v){
如果(此!=&v){
删除[]向量;
/*这里发生的是删除vect[],但是什么呢
如果下一行“vect=next int[v.tam];”抛出
例外?
*/
vect=新整数[v.tam];
for(int i=0;i

请看,这里将详细说明如何编写一个拷贝赋值操作符。

< p>你似乎正在学习15年前的C++。< /P>
  • 使用
    std::vector
    而不是编写自己的
    VectorDinamico
    • 这已经有了正确的副本、作业等
  • 如果无法执行1,请使用
    std::unique\u ptr
    而不是原始
    int*vect
    。这样就不用编写析构函数了。不过,您仍然需要编写副本和副本作业

    • 编写拷贝分配的规范正确方法是首先编写
      swap
      方法或重载,li
      VectorDinamico& VectorDinamico::operator=(VectorDinamico const &other) {
          VectorDinamico tmp(other);
          tmp.swap(*this);
      }
      
      //Here is my problem ( I think )
      //anyway I've left it empty, because I think it uses the Conjunto destructor's
      SetConjuntos::~SetConjuntos(){
          //delete []conjuntos; ( Cause segmetation fault )
      }