This question already has answers here:
Closed 11 years ago.
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 and delete [] 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 with delete. 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 at p (whether it is an array or not). On the other hand delete[] additionally runs through each element of the array and calls the destructor. Since normal data types like char don't have destructors, there is no effect, so delete and delete[] 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.
char * a = new char[1024];
delete a; // the incorrect way. also NO memory leak.
No. It doesn't gaurantee No memory leak. It in fact invokes undefined behavior.
delete and delete[] seemingly being equivalent in g++ is pure luck. Calling delete on memory allocated with new[], and vice versa, is undefined behaviour. Just don't do it.
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 needed delete[], 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.
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 you delete (just like vectorized new for constructors).
what your doing just free's the memory like its a pointer array.
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.
Related
This is a question that's been nagging me for some time. I always thought that C++ should have been designed so that the delete operator (without brackets) works even with the new[] operator.
In my opinion, writing this:
int* p = new int;
should be equivalent to allocating an array of 1 element:
int* p = new int[1];
If this was true, the delete operator could always be deleting arrays, and we wouldn't need the delete[] operator.
Is there any reason why the delete[] operator was introduced in C++? The only reason I can think of is that allocating arrays has a small memory footprint (you have to store the array size somewhere), so that distinguishing delete vs delete[] was a small memory optimization.
It's so that the destructors of the individual elements will be called. Yes, for arrays of PODs, there isn't much of a difference, but in C++, you can have arrays of objects with non-trivial destructors.
Now, your question is, why not make new and delete behave like new[] and delete[] and get rid of new[] and delete[]? I would go back Stroustrup's "Design and Evolution" book where he said that if you don't use C++ features, you shouldn't have to pay for them (at run time at least). The way it stands now, a new or delete will behave as efficiently as malloc and free. If delete had the delete[] meaning, there would be some extra overhead at run time (as James Curran pointed out).
Damn, I missed the whole point of question but I will leave my original answer as a sidenote. Why we have delete[] is because long time ago we had delete[cnt], even today if you write delete[9] or delete[cnt], the compiler just ignores the thing between [] but compiles OK. At that time, C++ was first processed by a front-end and then fed to an ordinary C compiler. They could not do the trick of storing the count somewhere beneath the curtain, maybe they could not even think of it at that time. And for backward compatibility, the compilers most probably used the value given between the [] as the count of array, if there is no such value then they got the count from the prefix, so it worked both ways. Later on, we typed nothing between [] and everything worked. Today, I do not think delete[] is necessary but the implementations demand it that way.
My original answer (that misses the point):
delete deletes a single object. delete[] deletes an object array. For delete[] to work, the implementation keeps the number of elements in the array. I just double-checked this by debugging ASM code. In the implementation (VS2005) I tested, the count was stored as a prefix to the object array.
If you use delete[] on a single object, the count variable is garbage so the code crashes. If you use delete for an object array, because of some inconsistency, the code crashes. I tested these cases just now !
"delete just deletes the memory allocated for the array." statement in another answer is not right. If the object is a class, delete will call the DTOR. Just place a breakpoint int the DTOR code and delete the object, the breakpoint will hit.
What occurred to me is that, if the compiler & libraries assumed that all the objects allocated by new are object arrays, it would be OK to call delete for single objects or object arrays. Single objects just would be the special case of an object array having a count of 1. Maybe there is something I am missing, anyway.
Since everyone else seems to have missed the point of your question, I'll just add that I had the same thought some year ago, and have never been able to get an answer.
The only thing I can think of is that there's a very tiny bit of extra overhead to treat a single object as an array (an unnecessary "for(int i=0; i<1; ++i)" )
Adding this since no other answer currently addresses it:
Array delete[] cannot be used on a pointer-to-base class ever -- while the compiler stores the count of objects when you invoke new[], it doesn't store the types or sizes of the objects (as David pointed out, in C++ you rarely pay for a feature you're not using). However, scalar delete can safely delete through base class, so it's used both for normal object cleanup and polymorphic cleanup:
struct Base { virtual ~Base(); };
struct Derived : Base { };
int main(){
Base* b = new Derived;
delete b; // this is good
Base* b = new Derived[2];
delete[] b; // bad! undefined behavior
}
However, in the opposite case -- non-virtual destructor -- scalar delete should be as cheap as possible -- it should not check for number of objects, nor for the type of object being deleted. This makes delete on a built-in type or plain-old-data type very cheap, as the compiler need only invoke ::operator delete and nothing else:
int main(){
int * p = new int;
delete p; // cheap operation, no dynamic dispatch, no conditional branching
}
While not an exhaustive treatment of memory allocation, I hope this helps clarify the breadth of memory management options available in C++.
Marshall Cline has some info on this topic.
delete [] ensures that the destructor of each member is called (if applicable to the type) while delete just deletes the memory allocated for the array.
Here's a good read: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=287
And no, array sizes are not stored anywhere in C++. (Thanks everyone for pointing out that this statement is inaccurate.)
I'm a bit confused by Aaron's answer and frankly admit I don't completely understand why and where delete[] is needed.
I did some experiments with his sample code (after fixing a few typos). Here are my results.
Typos:~Base needed a function body
Base *b was declared twice
struct Base { virtual ~Base(){ }>; };
struct Derived : Base { };
int main(){
Base* b = new Derived;
delete b; // this is good
<strike>Base</strike> b = new Derived[2];
delete[] b; // bad! undefined behavior
}
Compilation and execution
david#Godel:g++ -o atest atest.cpp
david#Godel: ./atest
david#Godel: # No error message
Modified program with delete[] removed
struct Base { virtual ~Base(){}; };
struct Derived : Base { };
int main(){
Base* b = new Derived;
delete b; // this is good
b = new Derived[2];
delete b; // bad! undefined behavior
}
Compilation and execution
david#Godel:g++ -o atest atest.cpp
david#Godel: ./atest
atest(30746) malloc: *** error for object 0x1099008c8: pointer being freed was n
ot allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
Of course, I don't know if delete[] b is actually working in the first example; I only know it does not give a compiler error message.
I have the following below code snippet
class test{
private:
int *ptr;
public:
test(int *myptr){
ptr = myptr;
}
~test(){
delete ptr;
}
};
int main(){
int* myptr = new int;
*myptr = 10;
test obj(myptr);
delete myptr;
}
Is there a memory leak happening in this program, if I dont do a new to pointer in the class will space be allocated for that pointer?
Rule of thumb for dealing with allocating member: every new/new[] should be paired with exactly one delete/delete[]. If you are missing the delete, then you have a memory leak (you have allocated memory that you never clean up). If you are delete-ing multiples times, as you are doing in this code example, you will have memory corruption issues.
How are you delete-ing multiple times? In main(), you allocate a pointer:
int* myptr = new int;
You give a copy of that pointer to your test object, obj. Then, at the end of the scope we have:
{
// ...
delete myptr;
~test(); // implicit, which also does delete myptr
}
Only one of those two places should be responsible for delete-ing the pointer. Which one is based on the semantics of your code. Does test own the pointer? In which case, it should delete it but main() should not. Does it simply observe the pointer? In which case, it should not delete it. With C++11, we have new smart pointers to express this idea better.
I'd encourage you to browse the definitive C++ book list as concepts like this are very crucial to understanding C++ but also very difficult to explain properly in a short Q&A format.
You should only delte a pointer once in ~test() or delete directly
*** Error in `./a.out': double free or corruption (fasttop): 0x08d13a10 ***
Consider using std::shared_ptr<int> or std::unique_ptr<int>, since direct memory management is discouraged in modern C++ unless you've a reason to do so.
You can read about semantics differences of smart pointers here, and the reference for them is here.
It will crash when exit main function, a allocated in heap memory can't be release two times
What will happen in your instance is that the pointer will be given to delete in main(), then the same pointer value will be given a second time to delete in the destructor of obj. This is undefined behaviour, so it might work, or it might not, in any case, it isn't guaranteed to work, and therefore such a construct should not be used.
Ordinarily you would establish ownership rules, e.g. whether the constructor “takes ownership” (and is therefore responsible for freeing resources) is up to you, but typically, and especially in modern C++, ownership semantics can be clearly achieved by using std::unique_ptr and std::shared_ptr.
Most importantly, whichever method you use to determine ownership, make sure you are consistent! Avoid complicated ownership semantics, as it will make it much more difficult to detect memory-related issues (or more generally, resource-related issues).
Contrary to what other people have said: you do not delete pointers in C++, but objects.
What's the difference?
Let's simplify your code a bit:
int *myptr = new int; // 1
int *ptr = myptr; // 2
delete myptr; // 3
delete ptr; // 4
As far as the usage of new and delete is concerned, this is the same code - I've just removed the class, since it's not relevant to the point here.
This code does the following:
new int allocates an int, and returns its address. The address is then stored in myptr.
The address is copied to ptr. Both ptr and myptr contain the address of the int that was just allocated.
The int is deallocated.
The int is deallocated... but it was already deallocated? Oops!
If you're lucky, your program will crash at this point.
delete myptr; has nothing to do with the variable myptr, except that myptr holds the address of the thing to delete.
It doesn't even have to be a variable - you could do delete new int; (although it wouldn't be very useful) or delete someFunctionThatReturnsAnAddress();, or int *p = 1 + new int[2]; delete [] (p - 1);.
Your class has only a reference of the allocated integer. Consider to declare it int const* ptr, then you cant delete it inside the class.
You should remove delete ptr from the destructor.
Usually the scope which is allocating something is responsible for freeing it. In your case the main routine is allocating and has to free.
For your question "Is there a memory leak happening in this program", the answer is No, but an exception is rasing.
Your code logic is not good, you should delete the pointer at where it was created. In this example, you shouldn't delete ptr in destructor function.
int* func()
{
int* i=new int[1];
//do something
return i;
}
void funcc()
{
int* tmp=func();
//delete allocated memory after use
delete tmp;
}
should delete working as described in the second function be a correct use ?
I think I didn't allocate memory to it by new ? new was used in the first, to be sure.
It should be delete [] tmp; because you're doing array new, but otherwise, it's correct.
As others have stated, you should use delete[] to delete arrays, not delete.
But, if you're asking whether it's okay to delete tmp because the memory it points to wasn't allocated with new, then your premise is incorrect.
It was allocated with new. The address of the memory that you allocate within the function for i is passed back to be stored in tmp, so it does point to memory that was allocated by new.
You're correct that i itself is out of scope at that point but memory allocated by new survives the scope change on exit from the function. And, since you're storing its location into tmp, you still have access to it.
Hence the deletion (once you make it an array deletion with []) is quite valid.
This is Undefined Behaviour™. You can only use delete if you used new. If you used new[], you MUST delete[] it. More than that, this is hideously unsafe code- you need a smart pointer.
No. new T[] should match delete []t. And new T should match delete t. Otherwise, your code would invoke undefined bevavior.
And it doesn't matter if you do delete []tmp outside the function. Its okay to do so. All that you need to keep in mind that the form of delete.
My spidey-senses tell me that you're wondering whether the dynamically-allocated int that you create in func is the same one that you attempt to delete in funcc.
The answer is: yes. Although you don't use strictly the same pointer variable, both pointers point to the same object.
However, please remember to use delete[] (with the []) when you used new[] (with the []). Your code is broken until you fix this.
Also, try to avoid newing in one place and deleteing in another. Perhaps consider a std::vector instead, which is far less error-prone.
I came across this kind of code once in a while - I suspect the creator is/was afraid that table delete would iterate over the table and "cost performance" (which imho will not be done either way)... is there any real benefit one might get/consider/imagine from not using the the table delete here?
myClass** table = new myClass* [size];
... //some code that does not reallocate or change the value of the table pointer ;)
delete table; // no [] intentionally
If you do this, you will get what the C++ Standard calls undefined behaviour - anything could happen.
That is a memory leak. A new [] must be matched by a delete []. Further, since table is a pointer to the first element of an array of pointers, any array member, if it's an array by itself will need to be de-allocated using a delete [].
Not only is there no benefit, the code is just plain wrong -- at best, it leaks memory, and at worst, it can crash your program or open up a hard-to-find security hole. You must always match new with delete and new[] with delete[]. Always.
There's really no reason to write like that and a serious reason to never do so.
It's true that for types with trivial destructors (like raw pointers in your case) there's no need to know the actual number of elements in the array and so the compiler might decide to map new[] and delete[] onto new and delete to reduce the overhead. If it decides this way you can't stop it without extra steps taken, so this compiler optimization will take place without your notice and will be free.
At the same time someone using your code might wish to overload the global operators new and delete (and new[] and delete[] as well). If that happens you run into big trouble because this is when you may really need the difference between the delete and delete[].
Add to this that this compiler-dependent optimization is unportable.
So this is the case when you get no benefits displacing delete[] with delete but risk big time relying into undefined behaviour.
It's definitely wrong as a s new[] needs to be paired with delete[]. If you don't you will get undefined behavior.
It may work (partially), because most implementations use new to implement new[]. The only difference for such an implementation would be that it would only call 1 destructor (for the first element instead of all destructors. But avoid it as it is not legal c++.
In theory you should call delete [].
EDIT: The following applies only to Microsoft Visual C++ (I should have said this).
In practice, in Microsoft Visual C++ , it doesn't matter which delete you use when the objects in the array don't have destructors. Since you have an array of pointers, and pointers can't have destructors, you should be OK.
However, as others have pointed out, it is incorrect C++ to mix new [] and delete without []. Although it may work in Visual C++ in this case, the code is not portable and may fail in other compilers.
But going back to the specific case of Visual C++, even if you call delete [], the compiler will realize that it doesn't need to iterate through the array calling destructors when it's an array of primitive types like int, char, or pointers. Calling delete in that case actually works and won't break anything. It would not be slower to do the right thing and call delete [], but it won't be faster either.
In fact, in MSVC++, delete[] p immediately calls the regular operator delete(void *p) when p is a pointer to a simple type, or one without destructors.
Those who don't believe me, step through this code into the CRT code for the first two calls to delete[].
#include "stdafx.h"
#include <malloc.h>
#include <iostream>
using namespace std;
class NoDestructor
{
int m_i;
};
class WithDestructor
{
public:
~WithDestructor()
{
cout << "deleted one WithDestructor at " << (void *) this<< endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
int **p = new int *[20];
delete [] p;
p = (int**) malloc(80);
free(p);
NoDestructor *pa = new NoDestructor[20];
delete [] pa;
WithDestructor *pb = new WithDestructor[20];
delete [] pb;
return 0;
}
that statement will leave all of the myClass objects that were pointed to by all the pointers in the array hanging around in memory. It also leaves the array of pointers in memory. There is no way that can be helpful, as it only frees up 32 bits of memory, and the OS still thinks you have (size) myClasses and pointers to each in use. This is just an example of a programmer not cleaning up after themself properly.
Check with the section [16.11] "How do I allocate / unallocate an array of things?" and beyond in C++ FAQ Lite,
http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.11
They explain that the array delete is a must when an array is created.
The instanced of myClass pointed to by the elements of your array should also be deleted where they are created.
This is a question that's been nagging me for some time. I always thought that C++ should have been designed so that the delete operator (without brackets) works even with the new[] operator.
In my opinion, writing this:
int* p = new int;
should be equivalent to allocating an array of 1 element:
int* p = new int[1];
If this was true, the delete operator could always be deleting arrays, and we wouldn't need the delete[] operator.
Is there any reason why the delete[] operator was introduced in C++? The only reason I can think of is that allocating arrays has a small memory footprint (you have to store the array size somewhere), so that distinguishing delete vs delete[] was a small memory optimization.
It's so that the destructors of the individual elements will be called. Yes, for arrays of PODs, there isn't much of a difference, but in C++, you can have arrays of objects with non-trivial destructors.
Now, your question is, why not make new and delete behave like new[] and delete[] and get rid of new[] and delete[]? I would go back Stroustrup's "Design and Evolution" book where he said that if you don't use C++ features, you shouldn't have to pay for them (at run time at least). The way it stands now, a new or delete will behave as efficiently as malloc and free. If delete had the delete[] meaning, there would be some extra overhead at run time (as James Curran pointed out).
Damn, I missed the whole point of question but I will leave my original answer as a sidenote. Why we have delete[] is because long time ago we had delete[cnt], even today if you write delete[9] or delete[cnt], the compiler just ignores the thing between [] but compiles OK. At that time, C++ was first processed by a front-end and then fed to an ordinary C compiler. They could not do the trick of storing the count somewhere beneath the curtain, maybe they could not even think of it at that time. And for backward compatibility, the compilers most probably used the value given between the [] as the count of array, if there is no such value then they got the count from the prefix, so it worked both ways. Later on, we typed nothing between [] and everything worked. Today, I do not think delete[] is necessary but the implementations demand it that way.
My original answer (that misses the point):
delete deletes a single object. delete[] deletes an object array. For delete[] to work, the implementation keeps the number of elements in the array. I just double-checked this by debugging ASM code. In the implementation (VS2005) I tested, the count was stored as a prefix to the object array.
If you use delete[] on a single object, the count variable is garbage so the code crashes. If you use delete for an object array, because of some inconsistency, the code crashes. I tested these cases just now !
"delete just deletes the memory allocated for the array." statement in another answer is not right. If the object is a class, delete will call the DTOR. Just place a breakpoint int the DTOR code and delete the object, the breakpoint will hit.
What occurred to me is that, if the compiler & libraries assumed that all the objects allocated by new are object arrays, it would be OK to call delete for single objects or object arrays. Single objects just would be the special case of an object array having a count of 1. Maybe there is something I am missing, anyway.
Since everyone else seems to have missed the point of your question, I'll just add that I had the same thought some year ago, and have never been able to get an answer.
The only thing I can think of is that there's a very tiny bit of extra overhead to treat a single object as an array (an unnecessary "for(int i=0; i<1; ++i)" )
Adding this since no other answer currently addresses it:
Array delete[] cannot be used on a pointer-to-base class ever -- while the compiler stores the count of objects when you invoke new[], it doesn't store the types or sizes of the objects (as David pointed out, in C++ you rarely pay for a feature you're not using). However, scalar delete can safely delete through base class, so it's used both for normal object cleanup and polymorphic cleanup:
struct Base { virtual ~Base(); };
struct Derived : Base { };
int main(){
Base* b = new Derived;
delete b; // this is good
Base* b = new Derived[2];
delete[] b; // bad! undefined behavior
}
However, in the opposite case -- non-virtual destructor -- scalar delete should be as cheap as possible -- it should not check for number of objects, nor for the type of object being deleted. This makes delete on a built-in type or plain-old-data type very cheap, as the compiler need only invoke ::operator delete and nothing else:
int main(){
int * p = new int;
delete p; // cheap operation, no dynamic dispatch, no conditional branching
}
While not an exhaustive treatment of memory allocation, I hope this helps clarify the breadth of memory management options available in C++.
Marshall Cline has some info on this topic.
delete [] ensures that the destructor of each member is called (if applicable to the type) while delete just deletes the memory allocated for the array.
Here's a good read: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=287
And no, array sizes are not stored anywhere in C++. (Thanks everyone for pointing out that this statement is inaccurate.)
I'm a bit confused by Aaron's answer and frankly admit I don't completely understand why and where delete[] is needed.
I did some experiments with his sample code (after fixing a few typos). Here are my results.
Typos:~Base needed a function body
Base *b was declared twice
struct Base { virtual ~Base(){ }>; };
struct Derived : Base { };
int main(){
Base* b = new Derived;
delete b; // this is good
<strike>Base</strike> b = new Derived[2];
delete[] b; // bad! undefined behavior
}
Compilation and execution
david#Godel:g++ -o atest atest.cpp
david#Godel: ./atest
david#Godel: # No error message
Modified program with delete[] removed
struct Base { virtual ~Base(){}; };
struct Derived : Base { };
int main(){
Base* b = new Derived;
delete b; // this is good
b = new Derived[2];
delete b; // bad! undefined behavior
}
Compilation and execution
david#Godel:g++ -o atest atest.cpp
david#Godel: ./atest
atest(30746) malloc: *** error for object 0x1099008c8: pointer being freed was n
ot allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
Of course, I don't know if delete[] b is actually working in the first example; I only know it does not give a compiler error message.