Why can't we free() memory that was allocated by new?
I know free()
won't call the destructor, but what else will this cause besides that the me开发者_如何学Cmber variable won't be destructed properly?
Also, what if we delete
a pointer that is allocated by malloc
?
It is implementation defined whether new
uses malloc
under the hood. Mixing new
with free
and malloc
with delete
could cause a catastrophic failure at runtime if the code was ported to a new machine, a new compiler, or even a new version of the same compiler.
I know free() won't call the destructor
And that is reason enough not to do it.
In addition, there's no requirement for a C++ implementation to even use the same memory areas for malloc
and new
so it may be that you're trying to free memory from a totally different arena, something which will almost certainly be fatal.
Many points:
- It's undefined behaviour, and hence inherently risky and subject to change or breakage at any time and for no reason at all.
- (As you know)
delete
calls the destructor andfree
doesn't... you may have some POD type and not care, but it's easy for someone else to add say astring
to that type without realising there are weird limitations on its content. - If you
malloc
and forget to use placementnew
to construct an object in it, then invoke a member function as if the object existed (includingdelete
which calls the destructor), the member function may attempt operations using pointers with garbage values new
andmalloc
may get memory from different heaps.- Even if
new
callsmalloc
to get its memory, there may not be a 1:1 correspondence between thenew
/delete
and underlyingmalloc
/free
behaviour.- e.g.
new
may have extra logic such as small-object optimisations that have proven beneficial to typical C++ programs but harmful to typical C programs.
- e.g.
- Someone may overload
new
, or link in a debug version ofmalloc
/realloc
/free
, either of which could break if you're not using the functions properly. - Tools like ValGrind, Purify and Insure won't be able to differentiate between the deliberately dubious and the accidentally.
- In the case of arrays,
delete[]
invokes all the destructors andfree()
won't, but also the heap memory typically has a counter of the array size (for 32-bit VC++2005 Release builds for example, the array size is in the 4 bytes immediately before the pointer value visibly returned bynew[]
. This extra value may or may not be be there for POD types (not for VC++2005), but if it isfree()
certainly won't expect it. Not all heap implementations allow you to free a pointer that's been shifted from the value returned bymalloc()
.
An important difference is that new and delete also call the constructor and destructor of the object. Thus, you may get unexpected behavior. That is the most important thing i think.
Because it might not be the same allocator, which could lead to weird, unpredictable behaviour. Plus, you shouldn't be using malloc/free at all, and avoid using new/delete where it's not necessary.
It totally depends on the implementation -- it's possible to write an implementation where this actually works fine. But there's no guarantee that the pool of memory new
allocates from is the same pool that free()
wants to return the memory to. Imagine that both malloc()
and new
use a few bytes of extra memory at the beginning of each allocated block to specify how large the block is. Further, imagine that malloc()
and new
use different formats for this info -- for example, malloc()
uses the number of bytes, but new
uses the number of 4-byte long words (just an example). Now, if you allocate with malloc()
and free with delete
, the info delete
expects won't be valid, and you'll end up with a corrupted heap.
精彩评论