0

I have been working on a code in which I have a lot of classes. I am allocating memory to different arrays of objects in constructor. However I had a strange error while I thought everything was ok. for an example lets say I have a class named Points and it has a double array of points called data.

Okay I am posting all of the code now:

class Points
{
      double *data;

      Points::Points()
      { 
           data = new double [C_NUMBER_OF_POINTS];
      }

      Points::~Points()
      {
           delete [] this->data;
      }
};

After debugging I found out that the error was with the this pointer, which I do not know why it is? The destructor is called to delete data, while the object is being destroyed, but it is still in memory. My question is why is it like this?

The error I was getting is basically due to mishandling of memory

Unhandled exception at 0x778f15de in HandTracker.exe: 0x00000000: The operation completed successfully. Blockquote

The error is fixed if I remove this pointer meaning if I use the following destructor

      Points::~Points()
      {
           delete []data;
      }

My question is not exactly about how to handle memory leaks, it's about this specific problem related with this pointer. What is the mechanism behind this pointer which makes it give this error?

masad
  • 1,547
  • 1
  • 18
  • 40

1 Answers1

2

Most likely, somewhere in your code you copied an instance of Points or constructed one from a reference to another. This created two instances of your class with the same data pointer. When the first one was destroyed, it destroyed the object that both instances had pointers to. When the second one was accessed or destroyed, it caused the problem, since the object was already gone.

The best fix is to avoid having a destructor by using well-tested classes that have their own destructors. For example, std::array (or std::vector) in this case. This will make everything "magically work" because these classes already have proper destructors, copy constructors, and copy assignment operators.

Otherwise, make sure you have correct copy constructor and copy assignment operators because the defaults (memberwise copy/duplicate) won't work in your case. See James McNellis' comment about the rule of three.

Try this:

Points::Points(const Points &a)
{
    data = new double[C_NUMBER_OF_POINTS];
    for (int i = 0; i < C_NUMBER_OF_POINTS; ++i)
          data[i] = a.data[i];
}

Points& operator=(const Points& a)
{ // The key is that this overrides the catastrophic default -- data=a.data;
     for (int i = 0; i < C_NUMBER_OF_POINTS; ++i)
           data[i] = a.data[i];
     return *this;
}
David Schwartz
  • 179,497
  • 17
  • 214
  • 278