TITLE: deletion of incomplete types (Newsgroups: comp.lang.c++.moderated, 9 Sep 98) [ Here is the original question that started this thread... -adc ] KNOWLES: Ian Knowles writes: >> Q. Does *standard* C++ permit "delete pUnknown" when pUnknown is a >> pointer to an incomplete class declaration? [ Its hard to believe, but its true. If you forward declare a class, you can legally delete a pointer to said class. In my opinion, this is almost always a coding error and I prefer compilers which warn when this occurs. -adc ] MYERS: Nathan Myers > >The destructor has nothing to do with it. Operator delete knows > >how many bytes are in *k because operator new stored the information > >"for later" before it returned. That's not why it's critical to have > >a virtual destructor; it's critical to have a virtual destructor so > >that the right destructor is called. KANZE: jkanze@otelo.ibmmail.com Exceptionally, Nathan is wrong here. The standard is quite clear; if the dynamic type and the static type are not identical, and the static type does not have a virtual destructor, the result is undefined behavior. (See paragraph 3, section 5.3.5.) Not calling the right destructor is one of the possible consequences. On most systems I've worked on, a core dump is one of the other consequences, at least if multiple inheritance is involved. The reason for this rule is simple; a pointer to a base class does not necessarily point to the start of the full object, and the pointer which the compiler passes to the operator delete function must be the same as that returned by the operator new function, that is, a pointer to the full object. The compiler typically will either call delete from within the actual destructor (using a hidden parameter to control whether delete is called or not), or have the destructor return a pointer to the full object. In both cases, this only works if the destructor is virtual, so that the destructor of the most derived class is called. SBNARAN: sbnaran@KILL.uiuc.edu > That was my question/point. Does the C++ standard say that operator > new must store the size of the thing it allocates? It seems to me > to be an implementation detail. In my previous post, I outlined a > an implementation where the size of the object is not stored in the > call to operator new. The implementation correctly determines the > number of bytes to deallocate at the delete statement! KANZE: The C++ standard requires that the operator delete be able to free the pointer returned by the operator new, without any additional information, since it is perfectly legal to call the functions directly, e.g.: void* p = ::operator new( n ) ; // ... ::operator delete( p ) ; How it does this is, of course, an implementation detail, but I've never seen an implementation which didn't use some form of hidden information. As pointed out above, the undefined behavior resulting from the lack of a virtual destructor is due to the requirement of finding the actual start address of the allocated block, and not the length. Given the correct start address, operator delete must be able to free the memory.