7

Does it actually work on some compilers/machines but on others it causes heap corruptions and crashes?

Does anyone have any insight into what going on under the covers?

trincot
  • 317,000
  • 35
  • 244
  • 286
crazyx
  • 17,806
  • 1
  • 17
  • 8
  • 10
    He's asking why you get this behavior, just telling him not to do it doesn't help further his understanding of anything. – bobDevil Aug 17 '10 at 18:52
  • 1
    @bobDevil: Okay, the behavior is undefined by the C++ standard, which means language implementors will not feel any desire to impose reasonable behavior. There is no traditional behavior (other than "Don't do that!"), so there isn't even an informal standard. Empirically, the behavior seems to vary. Therefore, you can't count on any particular behavior, and no compiler engineer is going to give you any sympathy. That is quite enough reason to say "Don't do it!" without going into any explanation as to why any particular behavior happens. – David Thornley Aug 17 '10 at 19:02
  • http://stackoverflow.com/questions/240212/what-is-the-difference-between-new-delete-and-malloc-free/240308#240308 – Martin York Aug 17 '10 at 19:10
  • Yes you're right, standard doesn't guarantee anything. I guess I was just reacting to the way it was answered. You're second comment, while mostly an angry retort to my comment, was much more helpful. – bobDevil Aug 17 '10 at 19:25
  • @bobDevil: Except that "That's undefined behavior; don't do it" IS the right thing to say. Making up scenarios about different possible behavior is mostly pointless and should be unnecessary. – David Thornley Aug 17 '10 at 22:00
  • 1
    I wonder, if a library reference says that a resource created by "CreateXX" must be released by "DestroyXX", would you still go to experiment what would happen if you called "DestroyYY" instead? Why is this such a popular question - almost as popular as "what is the result of `a = ++a;`"? – UncleBens Aug 17 '10 at 22:11
  • @UncleBens its probably because it is often the case that pointers get casted to void through many levels of indirection and errors result from not tracing all the way back how they were allocated. – crazyx Aug 18 '10 at 14:02

3 Answers3

19

C++ wants to call a destructor on the object when you use delete, but passing it to free doesn't allow this to happen. If the object contained other objects then those objects' destructors would not be called either. If the object had pointers in it then those wouldn't get freed.

Additionally C++'s new and delete could actually request a larger amount of memory from malloc and use the extra for book keeping (like storing the address of the destructor function), and so the pointer you passed to free would not actually be one that was malloced.

nategoose
  • 12,054
  • 27
  • 42
2

The standard says you have to match the allocation/deallocation function perfectly (new-delete, new[]-delete[], malloc-free). Theoretically, it is quite possible that some compilers implement operator new() as a simple malloc(), so it wouldn't cause a crash, but "only" skipping the destructor call (which is bad by itself). However, operator[] may store the number of elements in the allocated chunk of memory in which case, the address returned by new[] points inside some block allocated by malloc() (not to the beginning), which means you can't free it with free().

jpalecek
  • 47,058
  • 7
  • 102
  • 144
2

The new operator is also overloadable. If someone wrote a new operator that was doing something quite different, say grabbing pointers from a memory pool, calling free on those pointers could be very dangerous.

pythonic metaphor
  • 10,296
  • 18
  • 68
  • 110