Possible Duplicates:
How could pairing new[] with delete possibly lead to memory leak only?
( POD )freeing memory : is delete[] equal to delete?
Using gcc version 4.1.2 20080704 (Red Hat 4.1.2-48). Haven't tested it on Visual C++.
It seems that delete
and delete []
works the same when deleting arrays of "simple" type.
char * a = new char[1024];
delete [] a; // the correct way. no memory leak.
char * a = new char[1024];
delete a; // the incorrect way. also NO memory leak.
But, when deleting arrays of "complex" type, delete
will cause memory leak.
class A
{
public:
int m1;
int* m2; // a pointer!
A()
{
m2 = new int[1024];
}
~A()
{
delete [] m2; // destructor won't be called when using delete
}
};
A* a = new A[1024];
delete [] a; // the correct way. no memory leak.
A* a = new A[1024];
delete a; // the incorrect way. MEMORY LEAK!!!
My questions are:
- In the first test case, why
delete
anddelete []
are the same under g++? - In the second test case, why g++ doesn't handle it like the first test case?
This is all dependent on the underlying memory manager. Simply put, C++ requires that you delete arrays with
delete[]
and delete non-arrays withdelete
. There is no explanation in the standard for your behaviour.What's likely happening however is that
delete p;
simply frees the block of memory starting atp
(whether it is an array or not). On the other handdelete[]
additionally runs through each element of the array and calls the destructor. Since normal data types likechar
don't have destructors, there is no effect, sodelete
anddelete[]
end up doing the same thing.Like I said, this is all implementation specific. There's no guarantee that
delete
will work on arrays of any type. It just happens to work in your case. In C++ we call this undefined behaviour -- it might work, it might not, it might do something totally random and unexpected. You'd be best to avoid relying on undefined behaviour.No. It doesn't gaurantee
No memory leak
. It in fact invokes undefined behavior.Because that's undefined behavior. It's not guaranteed to break but it's not guaranteed to work either.
The delete expression calls the destructor of the object to be deleted before releasing the memory. Releasing the memory probably works in either case (but it's still UB), but if you use
delete
where you neededdelete[]
, then you aren't calling all the destructors. Since your complex object itself allocates memory which it in turn releases in its own destructor, you are failing to make all those deletions when you use the wrong expression.What is happening here is that when you call delete, the space taken up by the objects is deleted. In the case of chars, this is all you need to do (although it is still recommended to use delete[] because this is just g++. The actual behavior of calling delete on an array is undefined in the c++ standard.).
In the second example, the space taken up by you array is deallocated, including the pointer m2. However, what m2 is pointing to is not also deleted. When you call delete[] the destructor on each object in the array is called and then what m2 points to is deallocated.
they technically aren't the same, they just get optimized down to the same meaning on non-complex types. complex types require the vectorized
delete
so that the destructor can be called for every object in the array youdelete
(just like vectorizednew
for constructors).what your doing just free's the memory like its a pointer array.