C ++ remove pointer array - double free or corrupt

This is just a test project to understand how inheritance works. Cat is a subclass of Mammal, which is again a subclass of Animal.

int main() { Cat* cat1 = new Cat("nosy grey", 1.0d, 3); Cat* cat2 = new Cat("purply green", 2.0d, 4); Cat* cats[] = {cat1, cat2}; delete [] cats; } 

So I can’t do it, because then I get it.

 *** Error in `/home/max/git/info-2-ss/Blatt3/Aufgabe2/main.exe': double free or corruption (out): 0x00007fff55fd7b10 *** ======= Backtrace: ========= /lib/x86_64-linux-gnu/libc.so.6(+0x80a46)[0x7f3a07452a46] /home/max/git/info-2-ss/Blatt3/Aufgabe2/main.exe[0x40178e] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0x7f3a073f3ea5] /home/max/git/info-2-ss/Blatt3/Aufgabe2/main.exe[0x400d39] 

I exit when my constructors and destructors are called, so when my Cats are created, I get something like this:

 Called ctor of Animal with age: 3 Called ctor of Mammal with hairLength: 1 Called ctor of Cat with eyecolor: nosy grey 

When I change my code a bit, so it reads:

 delete [] *cats; 

then I would expect my dtors to be called like this for every Cat:

 Called dtor of Cat Called dtor of Mammal Called dtor of Animal 

instead, I get this single line:

 Called dtor of Cat 

Summary: How can I effectively remove my arrays so that all my dtors receive a call?

+6
source share
4 answers

You should use delete[] for the array only if you received this array from new ...[] ! Like this:

 Cat * cats = new Cat[2]; delete [] cats; 

The above would be correct. But keep in mind that, of course, in this case you cannot pass arguments to the constructor.

Now, your business. You did not create an array with new , therefore you should not delete the array itself (it is on the stack, not on the heap). This is why delete[] cats falls. Then *cats processes the array as a pointer and casts it, i.e. Returns the element that this pointer points to. For an array, this is the beginning of the array: *cats matches cats[0] . That is why only the first element is deleted in the second attempt.

Finally, the answer: instead of all this, delete each item separately . For your simple case:

 delete cat1; delete cat2; 

Or more generally:

 for(int i = 0; i < sizeof(cats)/sizeof(cats[0]); ++i) { delete cats[i]; } 

Here sizeof(cats)/sizeof(cats[0]) is a simple trick to get the number of elements in an array, dividing its size by the size of the element.

This frees up the memory in which all your Cat objects are located. If you are concerned about the memory in which your array of pointers is located, it is on the stack, which means that it will be automatically disabled when returning from the function.

+2
source

it

 Cat* cats[] = {cat1, cat2}; 

Creates an array of pointers to cats with automatic storage! You did not allocate the array with new[] , so you should not release it with delete[] .

+8
source
 for(i = 0; i < len(cats)/sizeof(Cat); i++) { delete cats[i]; } 

delete[] cats would only work if you created cats using cats = new Cat[num_cats] .

+2
source

You do not need to delete the array itself, just its elements. Your cats array is on the stack since you did not create it with new or malloc .

So all you have to do is

 delete cat1; delete cat2; 

or equivalent

 delete cats[0]; delete cats[1]; 
0
source

Source: https://habr.com/ru/post/945162/


All Articles