I am working on modifying a relatively large C++ program, where unfortunately it is not always clear whether someone before me used C or C++ syntax (this is in the electrical engineering department at a university, and we EEs are always tempted to use C for everything, and unfortunately in this case, people can actually get away with it).
However, if someone creates an object:
Packet* thePacket = new Packet();
Does it matter whether it is destroyed with delete thePacket;
or free(thePacket);
?
I realize that delete calls the destructor while free() does not, but Packet does not have a destructor. I am having a terrible time stuck in a memory management swamp here and I'm thinking this may be one of the many problems.
Packet
has a destructor, even if you haven't explicitly declared one. It has a default destructor. The default destructor probably doesn't actually do much, but you can't count on that being the case. It's up to the compiler what it does.new
andmalloc
also may have wildly different implementations. For example, delete is always called in a context where it has perfect information about the size of the data structure it's deleting at compile time.free
does not have this luxury. It's possible that the allocator thatnew
is using may not store the bytes at the beginning of the memory area stating how many bytes it occupies. This would leadfree
to do entirely the wrong thing and crash your program when freeing something allocated withnew
.Personally, if getting people to do the right thing or fixing the code yourself is completely impossible, I would declare my own global
operator new
that calledmalloc
so thenfree
would definitely not crash, even though it would still not call the destructor and be generally really ugly.If you call
free()
, the destructor doesn't get called.Also, there's no guarantee that
new
andfree
operate on the same heap.You can also override
new
anddelete
to operate specially on a particular class. If you do so, but callfree()
instead of the customdelete
, then you miss whatever special behavior you had written intodelete
. (But you probably wouldn't be asking this question if you had done that, because you'd know what behaviors you were missing..)Yes it does matter.
For memory obtained using
new
you must usedelete
.For memory obtained using
malloc
you must usefree
.new
andmalloc
may use different data structures internally to keep track of what and where it has allocated memory. So in order to free memory, you have to call that corresponding function that knows about those data structures. It is however generally a bad idea to mix these two types of memory allocation in a piece of code.In short, it is as bad as undefined behavior.
This is quiet self explanatory.
Yes it does matter.
free (thePacket)
would invoke Undefined Behaviour butdelete thePacket
would not and we all know Undefined Behaviour may have disastrous consequences.You are absolutely right, it is NOT correct. As you said yourself, free won't call the destructor. Even if Packet doesn't have an explicit destructor, it's using an inherited one.
Using
free
on an object created withnew
is like destroying only what a shallow-copy would reach. Deep-destroying NEEDS the destructor function.Also, I'm not sure objects created with new() are on the same memory map as malloc()'d memory. They are not guaranteed to be, I think.