0

say I created a custom Array class and have following constructor:

    Array::Array(size_t size)
    {
      mySize = size;
      //myData is of type int*
      myData = new int[mySize]; // this stuff is allocated on a heap
    }

To my knowledge, a default copy constructor in this case would be implemented like that:

    Array::Array(Array& a)
    {
      mySize = a.mySize;
      myData = a.myData; //points to the same memory on the heap
    }

Finally, say I have following code in my main.cpp file

     int main()
     {
       Array a(1);
       Array b(a); //copy constructor is invoked
     }

What I expected to be was a memory leak due to deletion of myData pointers to the free store memory, BUT I have following runtime error :

*** glibc detected *** ./main.out: double free or corruption (fasttop): 0x086ad008 ***

WHY? It seems that ~Array() somehow auto frees memory allocated on a heap - but this is very counter intuitive to me. Maybe I am missing something?

UPDATE:

      class Array{
         private:
           size_t mySize;
           int *myData;
           ...

UPDATE 2:

main.cpp:

   #include <iostream>
   #include "array.h"

   int main()
   {
     Array a(1);
     Array b(a);
   }

array.h:

   #ifndef ARRAY_H_
   #define ARRAY_H_
   #include <stddef.h>
   class Array{
   private:
       size_t mySize;
       int *myData;
   public:
       Array(size_t size);
       ~Array();
       void set(int i,int val);
       int get(int i);
       size_t getSize();
   };
   #endif

array.cpp:

   #include "array.h"

   Array::Array(size_t size)
   {
     mySize = size;
     myData = new int[mySize];
   }

   Array::~Array()
   {
     delete[] myData;
   }

   void Array::set(int i, int val)
   {
     if(i>=0 && i<mySize)
       myData[i] = val;
   }

   int Array::get(int i)
   {
     if(i>=0 && i<mySize)
       return myData[i];
     else return -1;
   }
   size_t Array::getSize()
   {
     return mySize;
   }

5 Answers5

4

I think in your destructor you have

 Array::~Array(void)
 {
      delete [] myData; //points to the same memory on the heap
 }

The problem is double free

Example:

int main()
{
       Array a(1);  // here a.myData = 0x12345678
       Array b(a); //copy constructor is invoked // here b.myData = 0x12345678

       // pop  stack (call destroy of object)
       // delete b.myData
       // delete a.myData already delete
}

Double free

EDIT: For your copy contructor use const because you don't modify a.

 Array::Array(const Array& a)
 {
      mySize = a.mySize;
      myData = a.myData; //points to the same memory on the heap
 }

Good Luck !

Quentin Perez
  • 2,833
  • 20
  • 22
3

So... despite your claims, it turns out you do delete the array in the destructor, and the copy constructor is a shallow copy, so you get a double delete. Simple.

Array::~Array()
{
  delete[] myData;
}

Since this is a dynamic array, it should own the data, therefore you are right to delete in the destructor, but you need to "deep" copy in the copy constructor and the assignment operator. See the rule of three.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
2

Your copy is a shallow copy, so IF you have a destructor that frees memory, each object attempts to delete the same memory.

You don't have to do a shallow copy. You could write your own explicit copy constructor that copies the actual data into a newly allocated array.

I like Google's suggestion to disable copy and assignment constructors and prefer explicit CopyFrom() methods.

1

"double free" means that the same pointer has been given to delete[] twice. because in your destructor (presumably) it's delete[]-ed both in object a and b. practical solution: use std::vector, don’t mess with raw arrays etc. needlessly.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • Oh, so maybe it is the case that delete[] is called automatically in destructor? – Vladislavs Burakovs Mar 06 '13 at 22:01
  • 1
    @ВладиславБураков: no it's not called automatically. presumably you, or whoever wrote code, put it there. it's difficult to say since you forgot to present that code. – Cheers and hth. - Alf Mar 06 '13 at 22:02
  • No, I didn't present the rest, because I didn't override anything else than constructor – Vladislavs Burakovs Mar 06 '13 at 22:03
  • @ВладиславБураков: uhm, the information you have given is inconsistent with reality. could you please present a **complete** small example that exhibits the described behavior. – Cheers and hth. - Alf Mar 06 '13 at 22:06
  • 1
    You've said *twice* now that you believe that `delete[]` is automatically called and you've been told that you're wrong. Can you post the *entire* code of the `Array` class, or a *complete, small example* that shows this error? – Nik Bougalis Mar 06 '13 at 22:08
0

I think your desctructors (from array 'a' and 'b') are trying to free the same memory (double free). Maybe you should check you myData before freeing.

FELIPE_RIBAS
  • 401
  • 1
  • 3
  • 14