Topic: Base pointer to array of Derived (was Borland C++)
Author: jamshid@emx.cc.utexas.edu (Jamshid Afshar)
Date: 17 Oct 1993 00:58:09 -0500 Raw View
In article <1993Oct13.071658.4996@usage.csd.unsw.oz.au>,
Vladimir Gilbourd <s9100767@cumulus.csd.unsw.OZ.AU> wrote:
>Compile, please, and run two simple patterns. ( Definitions of classes are
>equal for both cases). As you will see the output will be different.
The code is like:
#include <iostream.h>
class B
{ public:
virtual ~B() {cout<<"B::~B()\n";}
};
class D : public B
{ public:
~D() {cout<<"D::~D()\n";}
};
main() {
B *pp;
pp = new D[1];
delete [] pp;
}
Under one of the compilers Vladimir used, BC++ [3.1], the above
program does not call the D destructor. Under a few other compilers,
the D destructor is called, just as if the code were:
pp = new D;
delete pp;
>Who can explain why Borland gives different outputs?
You're code has a very subtle error. A `B*' can legally point to a B
object, to an object of a class derived from B, or to an array of B
objects. The expression `new D[1]' allocates an array of D objects
and the assignment `B* pp = new D[1];' causes `pp' to point to the
first element of D. That's perfectly fine. The problems start when
you try to use `pp' as a pointer to an array (eg, pp[3] or
delete[]pp). Since `pp' does not actually point to an array of `B'
objects, your use results in undefined behavior (eg, it might work, it
might sorta work, it might crash).
Apparently BC++ knows that when it deletes an array of objects, those
objects must be objects of the exact type `pp' points to. So, BC++
doesn't bother to do a virtual destructor call. I don't think there's
anything wrong with this optimization since it doesn't break correct
code.
Unfortunately, your error is, in general, impossible to catch at
compile time. It's like the following error:
void foo(B* p); // what if foo() assumes `p' is an array?
main() {
D d[5];
foo(d); // woops
}
The dangerous automatic conversion of "array of D" to "pointer to B"
is one of the many reasons to avoid general use of built-in arrays in
C++ (use an array class instead). Btw, if you've never read the
comp.lang.c FAQ section on arrays and pointers, please do -- I'm sure
you'll find it very enlightening.
Jamshid Afshar