Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

memory leak during creating class variable

using answers from operator overloading memory leak I added copy constructor and copy assingment operator, changed the operator+() as NathanOliver advised and now I am passing to constructor static array. Still have memory leak and strange thing is that I got this memory leak even when in main there is only class variable initialization, doesn't matter if with parameters or not... Any suggestions? I think cunstructor is valid.

Set::Set(int n, int* array){
   number = n; 
   elems = array;
   std::sort(elems, elems + number);
}

Set::Set(const Set& s){
   number=s.number;
   elems=s.elems;
}
Set& operator=(const Set& X){

   if(this==&X)
     return *this;
   delete [] elems;
   elems=X.elems;
   number=X.number;
   return *this;

I use gcc (tdm64-2) 4.8.1 compiler.

like image 451
ssukienn Avatar asked Apr 27 '26 22:04

ssukienn


1 Answers

There are two kinds of copy in c++, Shallow copy and Deep copy. The first just copies the pointers and the later copies the values. By default copy constructor and overload assignment operator do a shallow copy if generated by the compiler. Now lets take a look at your code.

Set::Set(int n, int* array){
   number = n; 
   elems = array;
   std::sort(elems, elems + number);
}

This constructor takes an in array. If this array is allocated on the heap using new then it should be deallocated using delete[]. Now the statement:

 elems = array;

is a shallow copy, it actually copies pointers not values. So if you accidentally delete array in main then elem will become a dangling pointer since it will point to a deleted array. Dereferencing or deleting elem after that will have undefined behaviour.

Now the same applies here:

Set& operator=(const Set& X){

   if(this==&X)
   return *this;
   delete [] elems;
   elems=X.elems;
   number=X.number;
   return *this;
}

You make again a shallow copy, you just copy pointers. In order to fix this you need

delete[] elems;
elems = new int[n]; //where n is x.elems length
//use memcpy() function or a for loop to copy the values of x.elems

Finally add a class destructor to your class:

~Set() {
     if(elems != nullptr) //check for empty array
         delete[] elems;
 }

Have in mind bjarne stroustrup the creator of c++ says that you should follow RIII (called R tripple i) . Basicly when you create a class always use new in constructor and delete in destructor. Avoid new/delete in any other function. Passing pointers can be tricky.

like image 151
KostasRim Avatar answered Apr 30 '26 10:04

KostasRim



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!