From 1440175224208819520
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,48e7669fcb7829f4,start
X-Google-Attributes: gidf78e5,public
X-Google-ArrivalTime: 1994-03-24 10:33:57 PST
Path: gmd.de!newsserver.jvnc.net!nntpserver.pppl.gov!princeton!att-in!csn!magnus.acs.ohio-state.edu!math.ohio-state.edu!cs.utexas.edu!swrinde!sgiblab!barrnet.net!parc!ellis
From: ellis@parc.xerox.com (John Ellis)
Newsgroups: comp.std.c++
Subject: delete and multiple inheritance breaks malloc?
Date: 24 Mar 1994 18:33:57 GMT
Organization: Xerox Palo Alto Research Center
Lines: 52
Message-ID: <2msmel$gs0@news.parc.xerox.com>
NNTP-Posting-Host: osric.parc.xerox.com

The draft standard of June 9, 1993 defines "delete" in a way that
breaks most malloc/free implementations.  Was this intentional, and if
so, did vendors participate in the discussion and seem aware of the
implications for implementations?

Section 5.3.4 says:

    ...the value of the operand of delete must be a pointer to a non-
    array object created by a new-expression without a new-placement
    specification, or a pointer to a sub-object representing a base
    class of such an object.

Under this definition (which makes perfect sense semantically), a
pointer to a multiply inherited sub-object can be passed to "delete".
In all known implementations, this can result in an interior pointer
(a pointer into the middle of a new-ed object) being passed to
"delete".

For example, the following program is legal:

    class A {int i;};
    class B {int i;};
    class C: public A, public B {int i;};

    void main() {
        for (;;) {
            B* b = new C;
            delete b; }}

But it crashes under Borland 4.0, GNU's g++ 2.5.8, Sun's CC (cfront
3.0), and Lucid's lcc 2.5.  Most C++ implementations of builtin
new/delete are based on C malloc/free.  But I know of no commercial
malloc/free that allows interior pointers to be passed to "free".

There are (at least) two implementation approaches for handling
interior pointers.  First, the allocator can maintain some kind of map
structure that allows arbitrary interior pointers to be mapped to the
base of an object.  Second, the compiler can add a header to every
sub-object that allows delete to find the base of the containing
object.

Maintaining a map adds non-trivial overhead and complexity to
allocators.  The overhead can be kept relatively low, but it requires
algorithms much more complex than the typical malloc/free.  (For
example, see the allocator in the Boehm garbage collector.)

Having the compiler add a header to every sub-object is feasible
according to the language definition, but as a practical matter this
wouldn't appeal to most of the C++ community.  For example, the RTTI
extension was limited to classes with virtual functions precisely to
avoid the overhead of adding an extra header word (the vptr) to
sub-objects that didn't have virtual functions.


