Ignoring programming style and design, is it \"safe\" to call delete on a variable allocated on the stack?
For example:
int nAmount;
delete &am
No, it is not safe to call delete
on a stack-allocated variable. You should only call delete
on things created by new
.
malloc
or calloc
, there should be exactly one free
. new
there should be exactly one delete
. new[]
there should be exactly one delete[]
. 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.
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).
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 tooperator delete(void*)
in the standard library shall be one of the values returned by a previous invocation of eitheroperator new(std::size_t)
oroperator 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.
Nobody can know what happens. This invokes undefined behavior, so literally anything can happen. Don't do this.
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.
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).