deleting array from heap

2019-06-16 01:50发布

My question is about deleting an array from heap memory. I read a book and this blog and other resources like this one, and all of them said that for deleting an array from heap we must use the [] after the delete function so if we write our codes without using [] then we have leaked memory.

for instance, consider below program

int *s = new int[10];
delete [] s;

I tested this little program in Linux by using the valgrind package(this package could check how much leaked memory produces by bad coding).By below command in Linux, we saw that everything is alright

sudo valgrind --leak-check=full ./<path_to_exe_file>

here is the output of Linux command

 ==4565== HEAP SUMMARY:
 ==4565==     in use at exit: 0 bytes in 0 blocks
 ==4565==   total heap usage: 1 allocs, 1 frees, 40 bytes allocated
 ==4565== 
 ==4565== All heap blocks were freed -- no leaks are possible

But MY question appeared when I try to use the delete without using [] and when I check the output of valgrind i saw all heap memory is freed so is it correct? or valgrind didn't know the whole heap isn't freed and some part of the array still is in there!!?? and if valgrind couldn't detect this kind of leaked memory so is there any package that can detect that.

2条回答
Anthone
2楼-- · 2019-06-16 02:33

Martin Broadhurst has already given the correct language-lawyer answer. I'm going to give the technical detail answer:

The point about using delete[] over delete is, that there is no way for the delete operator to know whether the passed pointer points to an array or to a single object. As such, delete only deletes a single object, while delete[] invokes some additional magic to recover the size of the array, and proceeds to delete all the elements.

Now deleting consists of two distinct parts:

  1. The objects must be destroyed by calling destructors. For an array, this means one destructor call for each array element.

  2. The memory that was used must be marked as free so that it may be reused. This is the job of the global operator delete() in C++. Since arrays are stored consecutively, this is a single call for the entire array.

valgrind is only concerned about memory. As such, it hooks memory allocating functions like malloc(), free(), operator new(), and operator delete().

What happens when you call delete instead of delete[] is, that the first object is destructed, and the pointer is passed on to operator delete(). operator delete() does not know about the object(s) that were stored inside the memory region, they are destroyed already anyway, so it will successfully mark the memory region as free. valgrind sees this operator delete() call, and is happy since all memory is free for reuse. However, your code failed to destruct all but the first array elements properly. And this is bad.

查看更多
神经病院院长
3楼-- · 2019-06-16 02:43

Calling delete on an array without using [] results in Undefined Behaviour. The Undefined Behaviour might be that the array is correctly deleted, which appears to be what you observed. You can't rely on this, however.

查看更多
登录 后发表回答