Article View: comp.std.c++
Article #3357Re: Correctness of compilers behavior
From: Steve Clamage
Date: Tue, 20 Feb 1996 21:42
Date: Tue, 20 Feb 1996 21:42
85 lines
4001 bytes
4001 bytes
In article UAA01735@kronstadt.rahul.net, Ian T Zimmerman <itz@rahul.net> writes:
>In article <4g3i93$9lp@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU
>(Fergus Henderson) writes:
>
>> > for (unsigned i=0; i<size; ++i) {
>> > (bptr+i)->~B();
>> > new(aptr+i) A;
>> > }
>> >
>
>> >int main(void)
>> >{
>> > A* arr=foo(2);
>> > delete [] arr;
>>
>> This has undefined behaviour. It contravenes 5.3.5[expr.delete]/2, which
>> says that the expression passed to `delete []' must be a pointer to the
>> first element of an array of objects allocated with `new []'; this is not
>> the case, because although there once was such an array at that memory
>> location, its lifetime ended when the memory was overwritten by the calls
>> to placement new (see 3.8[basic.life]/1).
>
>Is it relevant here that A and B are unrelated classes?
No. It only matters that A and B are not the same type. If A were derived
from B or vice-versa the code would still be wrong. Example:
class A : public B { ... };
B* p = new A[10]; // legal, but a bad idea
delete[] p; // error that does not have to be diagnosed
Such code is valid for single objects, but not for arrays. Although an A
is-a B, an array of A is NOT an array of B. Ordinarily you don't want
C-style arrays of objects, especially polymorphic objects. You probably
want an array of pointers so that you get object instead of value semantics,
or an array class of values to avoid the inconvenient properties of C-style
arrays.
>What about the following code?
>
>A a;
>
>A* as = new A [10];
>
>for (int i = 0; i < 10; ++i) {
> new (&as[i]) A(a);
>}
>delete [] as;
It is valid to construct an object on top of the storage previously
used for another object of the same type, so this code is mostly OK.
Notice that you don't destroy the objects that were constructed with
the default constructor.
In the general case you would want to destroy the original objects
before building new objects in their storage locations. Related to
this point, the compiler will construct the original objects from
index 0 up to index 9, and will destroy them in the reverse order.
If the objects have any inter-dependencies, you might need to
mimic that behavior to ensure a valid program. So you might write:
A* as = new A[10]; // construct as[0] through as[9] in that order
for( int i=10; --i>=0; )
as[i]->~A(); // destroy in reverse order
for( int i=0; i<10; ++i )
new (&as[i]) A(a); // contruct from as[0] through as[9]
...
delete[] as; // destroys as[9] down to as[0]
If all you want is an array of values, you don't have to go through the
extra construction and destruction if the number of elements is known
at compile time:
A as[10] = { a, a, a, a, a, a, a, a, a, a };
or perhaps
A as[10] = { A(arg0), A(arg1), A(arg2), ... , A(arg9) };
to get different values in different slots.
---
Steve Clamage, stephen.clamage@eng.sun.com
---
[ To submit articles: Try just posting with your newsreader. If that fails,
use mailto:std-c++@ncar.ucar.edu
FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Technical Details
Message-ID:
<4gdc37$cqv@engnews1.Eng.Sun.COM>Path:
arc1-ca.pugleaf.net!chronicle.mti.sgi.com!austernReferences:
<199602180416.UAA01735@kronstadt.rahul.net>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!chronicle.mti.sgi.com!austern From: clamage@Eng.Sun.COM (Steve Clamage) Newsgroups: comp.std.c++ Subject: Re: Correctness of compilers behavior Date: 20 Feb 1996 13:42:34 PST Organization: Sun Microsystems Inc. Approved: austern@isolde.mti.sgi.com Message-ID: <4gdc37$cqv@engnews1.Eng.Sun.COM> References: <199602180416.UAA01735@kronstadt.rahul.net> Reply-To: clamage@Eng.Sun.COM NNTP-Posting-Host: isolde.mti.sgi.com X-Original-Date: 20 Feb 1996 20:48:39 GMT X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBVAwUBMSpAYky4NqrwXLNJAQEWQAH/RkJZoKQGhF+SNUkGeSgA5GsjcvE7eemd DndF/IF8DUsEzYY/bOY4hnCNw7kf4JAoLDpk5bPMujB4razPHQPP4w== =Rh5f Originator: austern@isolde.mti.sgi.com