bsmile
bsmile

Reputation: 69

why would the way I used to call destructor cause memeory issue?

In the following code, if I include dealloc_dMAT into the destructor, it does not work. But if I call dealloc_dMAT specifically and then call the destructor, it works. Why would this be the case? The compiler I use is g++ 4.8.2 under linux.

The following code does not work,

#include <iostream>

using namespace std;

class QO{
  public:
    QO();
    ~QO();

    int DIM;         
    double **dMAT;   

    void alloc_dMAT();
    void dealloc_dMAT();

};


QO::QO(){

  DIM=4;
  cout << "DIM=" << DIM << endl;

  alloc_dMAT();

}
QO::~QO(){
  dealloc_dMAT();
}

void QO::alloc_dMAT(){
  dMAT=new double * [DIM];
  for(int i=0; i<DIM; i++) dMAT[i]=new double [DIM];
}
void QO::dealloc_dMAT(){
  for(int i=0; i<DIM; i++) delete [] dMAT[i];
  delete [] dMAT;
}




int main(){

  QO QB;
  //QB.dealloc_dMAT();
  QB.~QO();

  return 1;

}

But a slight modification on it works

#include <iostream>

using namespace std;

class QO{
  public:
    QO();
    ~QO();

    int DIM;
    double **dMAT;

    void alloc_dMAT();
    void dealloc_dMAT();

};


QO::QO(){

  DIM=4;
  cout << "DIM=" << DIM << endl;

  alloc_dMAT();

}
QO::~QO(){
  //dealloc_dMAT();
}

void QO::alloc_dMAT(){
  dMAT=new double * [DIM];
  for(int i=0; i<DIM; i++) dMAT[i]=new double [DIM];
}
void QO::dealloc_dMAT(){
  for(int i=0; i<DIM; i++) delete [] dMAT[i];
  delete [] dMAT;
}




int main(){

  QO QB;
  QB.dealloc_dMAT();
  QB.~QO();

  return 1;

}

EDIT: Thanks to Dave M.'s comment, it seems the code above does not fully display my issue, so here is a more accurate example of the trouble I ran into. If you compile and run it, you will notice the code abort at i=0, which should not happen if ~QO is called twice only when quitting the main.

#include <iostream>
#include <stdlib.h>

using namespace std;

class QO{
  public:
    QO();
    ~QO();

    int DIM;
    double **dMAT;

    void alloc_dMAT();
    void dealloc_dMAT();

};


QO::QO(){

  DIM=4;
  cout << "DIM=" << DIM << endl;

  alloc_dMAT();

}
QO::~QO(){
  dealloc_dMAT();
}

void QO::alloc_dMAT(){
  dMAT=new double * [DIM];
  for(int i=0; i<DIM; i++) dMAT[i]=new double [DIM];
}
void QO::dealloc_dMAT(){
  for(int i=0; i<DIM; i++) delete [] dMAT[i];
  delete [] dMAT;
}




int main(){

  for(int i=0; i<10; i++){
    QO QB;
    QB.~QO();
    cout << "i= " << i << endl;
  }

  system("pause");

  return 1;

}

Upvotes: 0

Views: 85

Answers (1)

Shadi
Shadi

Reputation: 1771

In the main, I would suggest that you comment the explicit destructor call like this:

  for(int i=0; i<10; i++)
    {
        QO QB;
        //QB.~QO();
        cout << "i= " << i << endl;
    }

Then you add a cout to the destructor like this:

QO::~QO()
{
  dealloc_dMAT();
  cout << "destructor called.";
}

This will give you a clear idea that you do not need to call the destructor explicitly as it is called implicitly each time the for scope exited.

also dMAT pointer is dangling pointer after the delete, so it is generally a good practice to assign it tonullptr although it might have no effect in some cases like when exiting the pointer scope right away after the deletion because the pointer itself no longer exists.

Upvotes: 1

Related Questions