Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ array of pointer memory leaks

In my class I have a dynamically allocated array of pointers. My declaration:

 array = new Elem* [size];
 for (int i = 0; i < size; i++) {
    array[i] = NULL;
 }

So there is an array of pointers, where each pointer points to a simple Elem struct.

The main question is, how should I properly deallocate the array. If I use only:

for (int i = 0; i < size; i++) {
   delete array[i];
}

Valgrind reports 1 not-freed block, which is traced to the line where 'array = new Elem* [size];' states.

On the other hand if I add to the previous code:

delete array;

Which I thought is correct, valgrind reports 0 not-freed blocks, which is perfect, BUT it reports

Mismatched free() / delete / delete []

exactly on the line where 'delete array;' is. I tried 'delete []array' too, but that's just "1 not-freed blocks" too then! If somebody could explain me the proper way it would be much appreciated.

EDIT: So using:

for (int i = 0; i < size; i++) {
   delete array[i];
}
delete[] array;

is working probably fine. It is working in one of my classes (I have two similar) the other still reports some small leak. I would think it's just a minor bug somewhere, but valgrind still points to the line where

array = new Elem* [size];

stands.

EDIT2: I solved this as well, thank you for your exhausting contribution!!

like image 674
tsusanka Avatar asked Jul 01 '26 19:07

tsusanka


1 Answers

You need:

delete [] array;

Because it's an array.

I just noticed your note that you tried this too - it's the proper thing to do so I don't know why you'd still be getting an error.

Edit: This deserves a more thorough explanation.

When you create a pointer using new, the pointer may be to a single element or an array of elements depending on the syntax you use. But the pointer type is the same in both cases! The compiler relies on you to know what the pointer points to and treat it accordingly.

Elem ** single = new Elem*;    // pointer to one pointer
single[0] = new Elem;          // OK
single[1] = new Elem;          // runtime error, but not compile time

Elem ** array = new Elem* [2]; // pointer to array of pointers
array[0] = new Elem;           // OK
array[1] = new Elem;           // OK

When you delete a pointer, the destructor is called for the object it points to or for each element of the array. But since the pointer type is the same in each case, the compiler relies on you to give it the proper syntax so it knows what to do.

delete single;
delete [] array;

In your case the elements of the array are pointers also, and pointers don't have destructors. That means those pointers won't be deleted and will become memory leaks if you don't delete them first. You were correct to have a loop to delete them individually before the final delete.

like image 59
Mark Ransom Avatar answered Jul 03 '26 13:07

Mark Ransom



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!