This question already has answers here:
Is delete[] equal to delete?
(6 answers)
Closed 9 years ago.
In C, free() is used to release the memory, say free(ptr). As I understand, extra memory is allocated before ptr in the library code to store the block size information. After free() is called, the whole block is tracked and then released.
In C++, there are two forms of new and delete. One is for array. If new[] is used, delete[] should be used. For example,
int ptr = new [10];
delete [] ptr;
Question 1: can I use delete ptr here? If that is OK, what if delete ptr + 2?
Question 2: If delete[] has to be used to match new[], why do we need two forms of delete? Just one form, say delete, would be enough.
Thanks for all the suggestions!
Thank Mgetz. Question 2 should be: why c++ standard proposed both delete [] and delete if there is only one correct form at any situation?
Q1: You can use delete, but it is wrong.
This will usually "work" insofar as it will correctly free the allocated memory, but it will not call destructors properly. For trivial types, you will often not see any difference, but that doesn't mean it isn't wrong anyway. In any case it is undefined behavior which you should avoid if you can (invoking UB forfeits any guarantees that your code will work, it might of course still work, but you can never be 100% sure).
Deleting ptr+2 is also undefined behavior and will almost certainly not "work", not even a little. Usually, this will simply result in a program crash.
Q2: You need the two because they mean different things. One means "delete this pointer-to-single-object" whereas the other means "delete this pointer-to-array-of-objects".
Obviously, the compiler needs to generate different code for those different things.
You need the two forms because, unlike malloc and free, new and delete do more than just allocate and deallocate memory; they also construct and destruct the object(s) respectively.
new and delete deal with scalar objects, while new[] and delete[] deal with arrays of objects.
When you call new T[n], it'll allocate enough memory for n copies of T, and then construct n instances within the allocated memory. Similarly, calling delete[] will cause destruction of those n instances followed by deallocation.
Obviously, since you do not pass n to delete[] that information is being stashed away somewhere by the implementation, but the standard doesn't require an implementation to destroy all n objects if you call delete instead. The implementation could just destroy the first object, it might behave correctly and destroy all n objects or it might cause demons to fly out of your nose.
Simply put, it's undefined behavior, there's no telling what'll happen, it's best imperative you avoid it.
Related
This question already has answers here:
How could pairing new[] with delete possibly lead to memory leak only?
(10 answers)
Closed 3 years ago.
In C++ is there any difference between the pointers p and q in the below code?
int* p = new int;
int* q = new int[5];
I understand that one allots new memory for a single int and the second allots memory for an array of 5 ints, but fundamentally is there any difference between a pointer pointing to a single int and one pointing to an array of ints?
I got this doubt because I read that one must use delete[] q to free up memory pointed to by q but just delete p for the single int pointed to by p.
What would happen if I used delete q?
The pointers themselves are completely indistinguishable. That's why you must remember to match new/delete and new[]/delete[].
Mismatching them triggers undefined behaviour.
When using new [] some c++ implementations will track the size of the allocation of the array in the address before the pointer returned. This is an implementation detail not defined by the standard.
The following answer describes this possible implementation in a little more detail: How could pairing new[] with delete possibly lead to memory leak only?
You must always match new with delete and new [] with delete []. It is Undefined Behavior to mix these.
In C++ is there any difference between the pointers p and q in the below code?
There is no visible difference between the pointers, but there certainly is one, and it is important. One is a pointer to an integer, the other is a pointer to an integer, which is also the first element in an array of a given size.
Unluckily, given only the pointer, you have no way of telling.
What would happen if I used delete q?
Probably nothing, but possibly a lot.
First of all, calling delete instead of delete[] will call the destructor exactly once, on the first element of the array, rather than on every element as it should. Now, the destructor for a trivial type like int doesn't do anything, so... as far as that goes, there is no real difference. There is, however, a huge difference for not-so-trivial types where the destructor (or chain of destructors) actually does something.
Second, you are interfering with proper deallocation of the underlying raw memory block. This can (and sometimes does) cause a hard crash. It might even cause a crash which occurs at a later time, in an unrelated, innocent piece of code, due to corruption earlier. Try and debug that.
Or, you might get a silent memory leak, it depends on the implementation and sometimes even on your "luck" in the particular case (e.g. hit a page boundary or not).
Because, well, allocating and freeing an array and allocating and freeing a single element just isn't the same thing. They are (usually) implemented slightly differently, and while the implementation may be able to cope with mismatched new/delete, that isn't guaranteed. You might get different behavior in the debugger compared to normal exection, too, whatever, anything.
Calling the wrong form of delete means invoking undefined behavior. Which basically means anything can happen. That includes "nothing" as well as "problem which is impossible to debug". It also includes the possibility of the compiler optimizing maliciously or just stripping out the entire surrounding function, or assuming a certain condition to be always-true. Which can lead to very nasty surprises on which you spend days and days trying to figure out what's going on.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why [] is used in delete ( delete [] ) to free dynamically allocated array?
Why does C++ still have a delete[] AND a delete operator?
I'm wondering what's their difference and I know the obvious answer some might say, that one is to delete an array and the other is to delete a single object but I'm wondering why should there be two different deletion methods for these two operations? I mean delete is basically implemented using C free method which doesn't care if the pointer is actually pointing toward an array or a single object. The only reason I can think of is two be able to know if it's an array and call destructor for each cell instead of only the first object but that wouldn't also be possible since compiler can not guess the length of array just looking at it's pointer. By the way though it's said to invoke undefined behavior to call delete for memory allocated with new[] I can't imagine anything that could possibly go wrong.
As you have discovered the compiler needs to know the length of an array (at least for non-trivial types) to be able to call destructors for each element. For this new[] typically allocates some extra bytes to record the element count and returns a pointer to the end of this bookkeeping area.
When you use delete[] the compiler will look at the memory before the array to find the count and adjust the pointer, so that the originally allocated block is freed.
If you use delete to destroy a dynamically allocated array, destructors for elements (except the first) won't be called and typically this will end up attempting to free a pointer that doesn't point to the beginning of an allocated block, which may corrupt the heap.
but that wouldn't also be possible since compiler can not guess the
length of array just looking at it's pointer
That's not really true. The compiler itself doesn't need to guess anything, but it does decide which function to call to free the memory based on the operator it sees. There is a separate function dedicated to releasing arrays, and this function does indeed know the length of the array to be freed so it can appropriately call destructors.
It knows the length of the array because typically new[] allocates memory that includes the array length (since this is known on allocation) and returns a pointer to just the "usable" memory allocated. When delete[] is called it knows how to access this memory based on the pointer to the usable part of the array that was given.
When you allocate memory using new[], the compiler not only needs to construct each element, it also needs to keep track of how many elements have been allocated. This is needed for delete[] to work correctly.
Since new and delete operate on scalars, they don't need to do that, and could save on a little bit of overhead.
There is absolutely no requirement for new to be compatible with delete[] and vice versa. Mixing the two is undefined behaviour.
Ignoring programming style and design, is it "safe" to call delete on a variable allocated on the stack?
For example:
int nAmount;
delete &nAmount;
or
class sample
{
public:
sample();
~sample() { delete &nAmount;}
int nAmount;
}
No, it is not safe to call delete on a stack-allocated variable. You should only call delete on things created by new.
For each malloc or calloc, there should be exactly one free.
For each new there should be exactly one delete.
For each new[] there should be exactly one delete[].
For each stack allocation, there should be no explicit freeing or deletion. The destructor is called automatically, where applicable.
In general, you cannot mix and match any of these, e.g. no free-ing or delete[]-ing a new object. Doing so results in undefined behavior.
Well, let's try it:
jeremy#jeremy-desktop:~$ echo 'main() { int a; delete &a; }' > test.cpp
jeremy#jeremy-desktop:~$ g++ -o test test.cpp
jeremy#jeremy-desktop:~$ ./test
Segmentation fault
So apparently it is not safe at all.
Keep in mind that when you allocate a block of memory using new (or malloc for that matter), the actual block of memory allocated will be larger than what you asked for.
The memory block will also contain some bookkeeping information so that when you free the block, it can easily be put back into the free pool and possibly be coalesced with adjacent free blocks.
When you try to free any memory that you didn't receive from new, that bookkeeping information wont be there but the system will act like it is and the results are going to be unpredictable (usually bad).
Yes, it is undefined behavior: passing to delete anything that did not come from new is UB:
C++ standard, section 3.7.3.2.3:
The value of the first argument supplied to one of thea deallocation functions provided in the standard library may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call to the deallocation function has no effect. Otherwise, the value supplied to operator delete(void*) in the standard library shall be one of the values returned by a previous invocation of either operator new(std::size_t) or operator new(std::size_t, const std::nothrow_t&) in the standard library.
The consequences of undefined behavior are, well, undefined. "Nothing happens" is as valid a consequence as anything else. However, it's usually "nothing happens right away": deallocating an invalid memory block may have severe consequences in subsequent calls to the allocator.
After playing a bit with g++ 4.4 in windows, I got very interesting results:
calling delete on a stack variable doesn't seem to do anything. No errors throw, but I can access the variable without problems after deletion.
Having a class with a method with delete this successfully deletes the object if it is allocated in the heap, but not if it is allocated in the stack (if it is in the stack, nothing happens).
Nobody can know what happens. This invokes undefined behavior, so literally anything can happen. Don't do this.
No,
Memory allocated using new should be deleted using delete operator
and that allocated using malloc should be deleted using free.
And no need to deallocate the variable which are allocated on stack.
An angel loses its wings... You can only call delete on a pointer allocated with new, otherwise you get undefined behavior.
here the memory is allocated using stack so no need to delete it exernally but if you have allcoted dynamically
like
int *a=new int()
then you have to do delete a and not delete &a(a itself is a pointer), because the memory is allocated from free store.
You already answered the question yourself. delete must only be used for pointers optained through new. Doing anything else is plain and simple undefined behaviour.
Therefore there is really no saying what happens, anything from the code working fine through crashing to erasing your harddrive is a valid outcome of doing this. So please never do this.
It's UB because you must not call delete on an item that has not been dynamically allocated with new. It's that simple.
Motivation: I have two objects, A and B. I know that A has to be instantiated before B, maybe because B needs information calculated by A. Yet, I want to destruct A before B. Maybe I am writing an integration test, and I want server A to shut-down first. How do I accomplish that?
A a{};
B b{a.port()};
// delete A, how?
Solution: Don't allocate A on the stack. Instead, use std::make_unique and keep a stack-allocated smart pointer to a heap-allocated instance of A. That way is the least messy option, IMO.
auto a = std::make_unique<A>();
B b{a->port()};
// ...
a.reset()
Alternatively, I considered moving the destruction logic out of A's destructor and calling that method explicitly myself. The destructor would then call it only if it has not been called previously.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How does delete[] “know” the size of the operand array?
How does the delete in C++ know how many memory locations to delete
I know it's a rather simple question but I a not sure about the difference (if any) between this lines :
double * a = new double[100];
delete[] a;
delete a;
free ((void*)a);
First off, would all of these calls (used each without the others) work the same way and free sizeof(double)*100 bytes?
Which lead me to the 2nd question, how does the program keep track of the size of the allocated memory? For instance if I send my a pointer to a function, then delete[] this pointer from within my function, would I also free the same amount of memory?
Thanks
The difference, oversimplified, is this:
delete[] a;
Is correct. All others are incorrect, and will exhibit Undefined Behavior.
Now, in reality, on all the compilers I use daily, delete a; will do the right thing every time. But you should still not do it. Undefined Behavior is never correct.
The free call will also probably do the right thing in the real world, but only because the thing you're freeing doesn't have a non-default destructor. If you tried to free something that was a class with a destructor, for example, it definitely wouldn't work -- the destructor would never be called.
That's one of the big differences (not the only difference) between new/delete and malloc/free -- the former call the constructors and destructors, while the latter meerly allocate and dealocate space.
Incorporating something #Rob said in his now-deleted post:
The simple rule is this: every new[] requires exactly one delete[].
Every new requires exactly one delete. malloc requires free. No
mix-and-match is allowed.
As to the question of how delete[] knows how many elements to delete, please see this response to a previous duplicate question.
Someone correct me, if I'm wrong, but as far as I understand, you use delete when you previously allocated memory with new and delete[] after using new Type[]. And free is used when you have allocated memory using malloc.
See c++ reference on delete and free.
Regarding the array of doubles, the result of all forms is the same -- all the allocated memory is returned to the system. The difference in calling free vs. delete vs. delete[] is:
free only releases the memory (the size of memory allocated for a was stored by memory manager when calling new)
delete calls the destructor of allocated object before releasing the memory
delete[] calls the destructor of each element in the array before releasing the memory
The difference is important if destructor of the allocated object contains cleanup code which releases other memory or system resource such as file or socket descriptor allocated during the lifetime of an object.
It is a good habit in C++ to allways use deleteon single instances and delete[] on array of objects/primitives regardless of the content of destructor.
What is wrong with using delete instead of delete[]?
Is there something special happening under the covers for allocating and freeing arrays?
Why would it be different from malloc and free?
Objects created with new[] must use delete[]. Using delete is undefined on arrays.
With malloc and free you have a more simple situation. There is only 1 function that frees the data you allocate, there is no concept of a destructor being called either. The confusion just comes in because delete[] and delete look similar. Actually they are 2 completely different functions.
Using delete won't call the correct function to delete the memory. It should call delete[](void*) but instead it calls delete(void*). For this reason you can't rely on using delete for memory allocated with new[]
See this C++ FAQ
[16.13] Can I drop the [] when
deleteing array of some built-in type
(char, int, etc)?
No!
Sometimes programmers think that the
[] in the delete[] p only exists so
the compiler will call the appropriate
destructors for all elements in the
array. Because of this reasoning, they
assume that an array of some built-in
type such as char or int can be
deleted without the []. E.g., they
assume the following is valid code:
void userCode(int n) {
char* p = new char[n];
...
delete p; // ← ERROR! Should be delete[] p !
}
But the above code is wrong, and it
can cause a disaster at runtime. In
particular, the code that's called for
delete p is operator delete(void*),
but the code that's called for
delete[] p is operator
delete[](void*). The default behavior
for the latter is to call the former,
but users are allowed to replace the
latter with a different behavior (in
which case they would normally also
replace the corresponding new code in
operator new[](size_t)). If they
replaced the delete[] code so it
wasn't compatible with the delete
code, and you called the wrong one
(i.e., if you said delete p rather
than delete[] p), you could end up
with a disaster at runtime.
Why does delete[] exist in the first place?
Whether you do x or y:
char * x = new char[100];
char * y = new char;
Both are stored in char * typed variables.
I think the reason for the decision of delete, and delete[] goes along with a long list of decisions that are in favor of efficiency in C++. It is so that there is no enforced price to do a lookup of how much needs to be deleted for a normal delete operation.
Having 2 new and new[] seems only logical to have delete and delete[] anyway for symmetry.
The difference is that delete will only delete the entire memory range, but will only call the destructor for 1 object. delete[] will both delete the memory and call the destructor for every single object. If you do not use delete[] for arrays, it's only a matter of time before you introduce a resource leak into your application.
EDIT Update
According to the standard, passing an object allocated with new[] to delete is undefined. The likely behavior is that it will act as I described.
Stroustrup talks about the reasons for separate new/new[] and delete/delete[]` operators in "The Design and Evolution of C++" in sections 10.3 through 10.5.1:
10.3 Array Allocation - discusses that they wanted a way to allow arrays of objects to be allocated using a separate scheme from allocation single objects (ie., allocating arrays from a separate store). Adding the array versions of new and delete was a solution for this;
10.5.1 Deallocating Arrays - discusses how a problem with deallocating arrays using just a single delete operator is that there needs to be more information than just the pointer in order to determine if the pointer points to the first element of an array or if it just points to a single object. Instead of "complicating the common case of allocating and deallocating individual objects", the delete[] operator is used to handle arrays. This fits in with the general C++ design philiosophy of "don't pay for what you don't use".
Whether this decision was a mistake or not is debatable - either way has good arguments, but we have what we have.
The reason for this requirement is historical and because new type and new type [size] return different things that need to be cleaned up differently.
Consider this code
Foo* oneEntry = new Foo;
Foo* tenEntries = new Foo[10];
These both return a Foo* pointer, the difference is the second call will result in the Foo constructor being called 10x, and there being roughly 10x as much memory.
So now you want to free your objects.
For a single object you would call delete - e.g. delete oneEntry. This calls the objects destructor and and deallocates the memory.
But here's the problem - oneEntry and tenEntries are both just Foo pointers. The compiler has no idea whether they point to one, ten, or a thousand elements.
When you use the special syntax of delete []. This tells the compiler "this is an array of objects, figure out the count and then destruct them all".
What really happens is that for new type [size] the compiler secretly stores 'size' somewhere else. When you call delete[] it knows that this secret value exists so it can find out how many objects are in that block of memory and destruct them.
The question you could then ask is "why doesn't the compiler always store the size?"
That's a great question and it dates back to the early days of C++. There was a desire that for built-in types (char, int, float, etc) the following would be valid for C++;
int* ptr = new int;
free(ptr);
int* ptr = (int*)malloc(sizeof(int) * someSize);
delete ptr;
The reasoning behind this was an expectation that people would provide libraries that returned dynamically allocated memory, and users of these libraries would have no way of knowing whether to use free/delete.
This desire for compatibility meant that the size of an array could not be stored as part of the array itself and had to be kept elsewhere. Because of this overhead (and remember, this was back in the early 80's) it was decided to do this book keeping only for arrays and not single-elements. Thus arrays need a special delete syntax that looks up this value.
The reason malloc/free do not have this problem is that they simply deal with blocks of memory and do not have to worry about calling constructors/destructors.
As to the "why" in the title: one of the design goals of C++ was that there wouldn't be any hidden costs. C++ was also developed at a time when every byte of memory still mattered a whole lot more than it does today. Language designers also like orthogonality: if you allocate the memory with new[] (instead of new), you should free it with delete[].
I don't think there's any technical reason that new[] couldn't stick an "I'm an array" flag in the header of the memory block for delete (no more delete[]) to look at later.
new and delete are different from malloc and free in that malloc and free only allocate and free memory; they don't call ctors or dtors.
When you use new[] to allocate an array, you are actually telling C++ the size of the array. When you use malloc, you are instead telling it how much memory is allocated. In the former case, freeing based on the size of the array would not make sense. In this case, it does. But since there is no difference between a pointer for an array vs. for a single object, a separate function is needed.