Topic: Problem: delete zero length array with virtual dtor well-defined ?


Author: "J.Barfurth" <techview@bfk-net.de>
Date: 1999/03/04
Raw View
Is the result of the following well-defined ?

struct A {            ~A() {} };
struct B { virtual ~B() {} };

void do_some(unsigned n)
{
    A* arrayA = new A[n];
    B* arrayB = new B[n];

    delete[] arrayA;
    delete[] arrayB;    //   (*)
}

int main()
{
    do_some(0);
    return 1;
}

On VC6.0 (sorry: got nothing else here) this program crashes at (*).
As far as I recall, allocating memory of zero-size via new (or new[ ])
should yield a distinct non-NULL pointer (it does);
accordingly it should be possible to delete([ ]) this pointer somehow.

I dont have the standard nor the BS at hand (the guy who borrowed it never
showed up again), so here is the question:
- Is there anything stating this can or must result in undefined behaviour ?

Here is some code to show, why this -delete[]- is difficult for an
implementation:
struct C : B
{
    virtual ~C();
    void* operator new[](size_t);    // some private scheme
    void operator delete[](void*);    // matching scheme here
};

B* arrayC = new C[0];
delete[] arrayC;    // how do we get at the correct destructor, having no
vtable (no object instantiated)

BTW: If B has a constructor which throws, the correct operator delete[] gets
called to get rid of the memory (even in the case of new C[0]).

-- J   rg



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@bardeen.ceg.uiuc.edu (Siemel Naran)
Date: 1999/03/04
Raw View
On 4 Mar 1999 19:23:53 GMT, J.Barfurth <techview@bfk-net.de> wrote:

>Is the result of the following well-defined ?
>
>struct A {            ~A() {} };
>struct B { virtual ~B() {} };
>
>void do_some(unsigned n)
>{
>    A* arrayA = new A[n];
>    B* arrayB = new B[n];
>
>    delete[] arrayA;
>    delete[] arrayB;    //   (*)
>}
>
>int main()
>{
>    do_some(0);
>    return 1;
>}

Yes.  It is well defined.  Dynamic arrays of length 0 are allowed.
Egcs compiles and runs the above without a crash.


>On VC6.0 (sorry: got nothing else here) this program crashes at (*).
>As far as I recall, allocating memory of zero-size via new (or new[ ])
>should yield a distinct non-NULL pointer (it does);
>accordingly it should be possible to delete([ ]) this pointer somehow.

No, allocating a zero size array
   T * ptr=new T[0];
may yield null.  The bottom line is that "delete ptr" should have no
effect.

But if the implementation has "new T[0]" return a non-null pointer,
then the pointers should be distinct.

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Biju Thomas <bijuthom@ibm.net>
Date: 1999/03/05
Raw View
Siemel Naran wrote:
>
> allocating a zero size array
>    T * ptr=new T[0];
> may yield null.

It is not allowed to be NULL.

Quoting from 5.3.4/7 in the standard:

<quote>
When the value of the expression in a direct new declarator is zero, the
allocation function is called to allocate an array with no elements. The
pointer returned by the new expression is non-null.
</quote>

--
Best regards,
Biju Thomas


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: jim.hyslop@leitch.com
Date: 1999/03/05
Raw View
In article <7bmm4f$i4n$1@news.hamburg.pop.de>,
  "J.Barfurth" <techview@bfk-net.de> wrote:
>
> Is the result of the following well-defined ?
>
> struct A {            ~A() {} };
> struct B { virtual ~B() {} };
The code is well-defined, and should not crash.

I debugged the code, and discovered VC6 is not setting the vptr at all.  I
suggest you submit a bug report to Microsoft.

[snip]

Jim
Note to recruitment agencies:  I will not refer my friends or colleagues
to you nor do I want to use your services to find me a job.  I stop
reading unsolicited email as soon as I determine it is job-recruitment

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jim.hyslop@leitch.com
Date: 1999/03/05
Raw View
In article <36DEF043.85D94BBC@ibm.net>,
  bijuthom@ibm.net wrote:
[snip]
> Quoting from 5.3.4/7 in the standard:
>
> <quote>
> When the value of the expression in a direct new declarator is zero, the
> allocation function is called to allocate an array with no elements. The
> pointer returned by the new expression is non-null.
> </quote>

Presumably, though, "new(nothrow)T[0];" should be allowed to return NULL, in
the event of an allocation failure, right?

Jim
Note to recruitment agencies:  I will not refer my friends or colleagues
to you nor do I want to use your services to find me a job.  I stop
reading unsolicited email as soon as I determine it is job-recruitment

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/03/05
Raw View
J.Barfurth wrote:

[...]

> Here is some code to show, why this -delete[]- is difficult for an
> implementation:
> struct C : B
> {
>     virtual ~C();
>     void* operator new[](size_t);    // some private scheme
>     void operator delete[](void*);    // matching scheme here
> };
>
> B* arrayC = new C[0];
> delete[] arrayC;    // how do we get at the correct destructor, having no
> vtable (no object instantiated)

What do you need the destructor for, if there's no object to
destruct with it?

However, I can see a problem if operator delete[] is virtual.
(Is making operator delete[] virtual allowed?)

[...]


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: clamage@eng.sun.com (Steve Clamage)
Date: 1999/03/05
Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:

>However, I can see a problem if operator delete[] is virtual.
>(Is making operator delete[] virtual allowed?)

Member functions operator new and operator delete are static members,
whether you declare them static or not.

Since new is called before the constructor executes, and delete
is called after the destructor completes, I hope it is obvious
wny they can't have a "this" pointer or be virtual.

--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]