Forums before death by AOL, social media and spammers... "We can't have nice things"
|    comp.lang.c++.moderated    |    Moderated discussion of C++ superhackery    |    33,346 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 31,483 of 33,346    |
|    =?ISO-8859-1?Q?Daniel_Kr=FCgler?= to Agents Marlow    |
|    Re: deleting an array of objects and und    |
|    23 Sep 11 12:05:31    |
   
   522ced26   
   From: daniel.kruegler@googlemail.com   
      
   On 2011-09-23 15:09, Agents Marlow wrote:   
   > I have just come across something I didn't know from the std:   
   >   
   > When deleting an array, the dynamic and the static type of the object   
   > must be the same, or the behavior is undefined (C++ Standard 5.3.5/3).   
      
   Correct.   
      
   > I was amazed to discover this. It was revealed to me in a test   
   > question where it had a code fragment and said "what, if anything, is   
   > wrong with this code?". Here is the code:   
   >   
   > struct X {   
   > virtual ~X() {}   
   > };   
   >   
   > class Y : public X {   
   > };   
   >   
   > int main() {   
   > X* p = new Y[2];   
   > delete [] p;   
   > return 0;   
   > }   
   >   
   > The above code has undefined behaviour according to the std. But why?   
   > I really don't understand. The usual gotcha when doing polymorphic   
   > deletes is forgetting to make the dtor of the base class virtual but   
   > that has been done here and it's still undefined behaviour!   
      
   This is the root of the misunderstanding: The virtual destructor only   
   helps to make polymorphic deletes of *objects* of the corresponding type   
   well-defined, but you would need the concept of a virtual destructor for   
   array objects to make a polymorphic delete of the array well-defined.   
   But there does not exist such a concept in C++.   
      
   You can look at this the following way: array-new allocates a continuous   
   memory block for the whole number of elements (these are known   
   statically). Deleting this array via array-delete does not perform any   
   polymorphic action on the array elements, because they are statically   
   determined by the type of the array, so it does not help here that X has   
   a virtual destructor - only the statically determined destructor of the   
   element type will be invoked.   
      
   > If one wanted an array of base class pointers then how would one   
   > delete the objects when the time comes? Would it be ok to have a   
   > vector of boost::shared_ptrs?   
      
   This would work, because the std::vector will simply invoke the deleter   
   of the shared_ptr's which knows the correct deleter of it's pointee.   
   Note the difference: Here you are using an array of *pointer* to items.   
   But that was not what you used in your original example: There you used   
   an array of (non-pointer) elements.   
      
   > Or would that boil down to the above and   
   > thus yield undefined behaviour also? I am worried if the answer to   
   > that is "yes" because I have written such code recently. I hope it   
   > would be ok since the container is a vector rather than a native   
   > array.   
      
   This is OK.   
      
   > Perhaps it is native arrays that are the source of the trouble   
   > for reasons I don't understand.   
      
   The problem is one, which cannot happen with std::vector. You either   
   could form std::vector
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca