Search code examples
c++gccc++11gcc-warning

C++, copy constructor confusion


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;
   }

Solution

  • 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 !