[comp.lang.c++] delete

leo@atcmp.nl (Leo Willems) (07/27/90)

When shifting from 2.0 to 2.1 I found myself in problems with:

func(){
	classtype *m = new classtype[10];

	delete[10] m;
}

In 2.0 this works fine, in 2.1 not, that compilers suggests:

	delete [] m;

which indeed works correct. (but not in 2.0, which accepts the code but
generates a .c file with a syntax error)

Is delete[] indeed the correct way ?
Should delete[] be accepted by 2.0 or is it new to 2.1?

Thanks in advance, Leo


 Leo Willems			Internet: leo@atcmp.nl
 AT Computing			UUCP:     mcsun!hp4nl!kunivv1!atcmpe!leo
 P. O. Box 1428				
 6501 BK  Nijmegen		Phone:    +31-80-566880
 The Netherlands		Fax:	  +31-80-555887

lynch@cerc.utexas.edu (Tom Lynch) (07/28/90)

In article <641@atcmpe.atcmp.nl> leo@atcmp.nl (Leo  Willems) writes:
>When shifting from 2.0 to 2.1 I found myself in problems with:
>
>func(){
>	classtype *m = new classtype[10];
>
>	delete[10] m;
>}
>
>In 2.0 this works fine, in 2.1 not, that compilers suggests:
>
>	delete [] m;
>
>which indeed works correct. (but not in 2.0, which accepts the code but
>generates a .c file with a syntax error)
>
>Is delete[] indeed the correct way ?
>Should delete[] be accepted by 2.0 or is it new to 2.1?

delete m; would be sufficient.  delete [10] m is redundant

   Stroustrup p 259: 
        "In the form 
             delete [ expression ] expression
          the second expression points to a vector and first
          expression gives the number of elements of that vector.
          Specifying the number of elements is redundant except
          when deleting vectors of certain classes..."
 
 I don't know what delete [] m means.

-tom
lynch@cerc.utexas.edu          Nothing is absolute.

p.s. please send me a note if this posted.  Does anyone use the
     'F' in rn?  should it work?

rfg@NCD.COM (Ron Guilmette) (07/29/90)

In article <641@atcmpe.atcmp.nl> leo@atcmp.nl (Leo  Willems) writes:
>When shifting from 2.0 to 2.1 I found myself in problems with:
>
>func(){
>	classtype *m = new classtype[10];
>
>	delete[10] m;
>}
>
>In 2.0 this works fine, in 2.1 not, that compilers suggests:
>
>	delete [] m;
>
>which indeed works correct. (but not in 2.0, which accepts the code but
>generates a .c file with a syntax error)
>
>Is delete[] indeed the correct way ?

This is a relative recent change in the definition of the language, and in the
cfront implementation of the language.  Thus, it is not surprizing that it
has thrown some people for a loop.

The new Annotated C++ Reference Manual (E&S) clearly indicates that the
proper way to delete an array of things which are pointed to by some pointer
`p' is to say:

		delete [] p;

In the old days (e.g. when using 2.0 and earlier) you needed to write the
actual number of elements inside the [], but that's not needed anymore,
nor will it be in the future.

>Should delete[] be accepted by 2.0 or is it new to 2.1?

This is new in 2.1.  You will not be able to use this simpler notation/syntax
if you are still working with cfront 2.0 (or earlier).

P.S.  For anybody out there who is doing serious work with C++ and who has
not yet obtained a copy of the new Annotated C++ Reference Manual, I have
only two words for you.  Get it.

'nuff said.

-- 
// Ron Guilmette
// C++ Entomologist
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// Motto:  If it sticks, force it.  If it breaks, it needed replacing anyway.

hansen@pegasus.ATT.COM (Tony L. Hansen) (07/29/90)

< From: lynch@cerc.utexas.edu (Tom Lynch)
< delete m; would be sufficient.  delete [10] m is redundant

Absolutely NOT! Without the [], C++ does not know that it's an array of
objects to be deleted instead of a single object, and the destructors would
not be called for elements 1..m of the array.

<   Stroustrup p 259: 

Your reference is outdated. Get Stroustrup's latest work, coauthored with
Margaret Ellis, The Annotated C++ Reference Manual, a.k.a. E&S.

< I don't know what delete [] m means.

As I said, your reference is outdated. The latest C++ rules say that the
number within the [] is unnecessary and the environment is required to keep
track of how many elements are in the array.

					Tony Hansen
				att!pegasus!hansen, attmail!tony
				    hansen@pegasus.att.com

davidm@uunet.UU.NET (David S. Masterson) (07/31/90)

In article <4937@pegasus.ATT.COM> hansen@pegasus.ATT.COM (Tony L. Hansen)
writes:

   < From: lynch@cerc.utexas.edu (Tom Lynch)
   < delete m; would be sufficient.  delete [10] m is redundant

   Absolutely NOT! Without the [], C++ does not know that it's an array of
   objects to be deleted instead of a single object, and the destructors would
   not be called for elements 1..m of the array.

Why?  I could understand this if m were declared as a pointer and wound up
pointing to an array of 10 somethings, but, if m is declared as an array, then
why doesn't C++ know "that it's an array of objects to be deleted instead of a
single object"?

   < I don't know what delete [] m means.

   As I said, your reference is outdated. The latest C++ rules say that the
   number within the [] is unnecessary and the environment is required to keep
   track of how many elements are in the array.

Isn't this a contradiction of the previous statement?  If the environment is
keeping track of how many elements are in the array, then doesn't it know that
the variable names an array?
--
===================================================================
David Masterson					Consilium, Inc.
uunet!cimshop!davidm				Mt. View, CA  94043
===================================================================
"If someone thinks they know what I said, then I didn't say it!"

hansen@pegasus.ATT.COM (Tony L. Hansen) (07/31/90)

< From: cimshop!davidm@uunet.UU.NET (David S. Masterson)
<< From: <4937@pegasus.ATT.COM> hansen@pegasus.ATT.COM (Tony L. Hansen)
<<< From: lynch@cerc.utexas.edu (Tom Lynch)
<<< delete m; would be sufficient.  delete [10] m is redundant

<< Absolutely NOT! Without the [], C++ does not know that it's an array of

< Why?  I could understand this if m were declared as a pointer and wound up
< pointing to an array of 10 somethings, but, if m is declared as an array,
< then why doesn't C++ know "that it's an array of objects to be deleted
< instead of a single object"?

Let's start at the beginning and work forward.

    "X *x = new X" means to allocate an object of type X, using either
    operator X::new() or the global operator ::new(), invoke the appropriate
    constructor for that object, and assign a pointer to it to the pointer
    x.

    "X *x = new X[m]" means to allocate an array of objects of type X, using
    only the global operator ::new(), invoke the appropriate constructor for
    x[0] through x[m-1], and assign a pointer to the array to the pointer x.
    The 1990 definition of C++ also mandates that the C++ environment
    remember the value m associated with that pointer.

    "delete x" means to take the single object (of type X) that x points to
    and invoke ~X() followed by either operator X::delete() or the global
    operator ::delete().

    "delete [m] x" means to take the pointer that x points to, treat it as
    an array, invoke ~X() on x[0] through x[m-1], and then invoke the global
    operator ::delete(). This syntax is part of all versions of C++ from
    1985 through 1990. As of 1990, the syntax is deprecated, meaning that it
    will go away at some point.

    "delete [] x" means to take the pointer that x points to, treat it as an
    array, invoke ~X() on x[0] through x[m-1], where m is the number that was
    saved away by operator ::new when the array was allocated, and then
    invoke the global operator ::delete(). This syntax is part of the 1990
    definition of C++. Some compilers, in particular AT&T 2.1 cfront,
    support this syntax. The 2.1 cfront ignores any value passed within the
    [], just giving a warning message indicating that it is doing so.

    Note that the compiler is only supposed to look up the number if it is
    told that the pointer is pointing to an array by using the [] in
    "delete[] x". It does not look up the number for "delete x".

Now consider these two classes:

	class A {
	    double x;
	public:
	    A() { x = 3; }
	    double getx() { return x; }
	    void setx(double X) { x = X; }
	};

	class B {
	    double *x;
	public:
	    B() { x = new double; *x = 3; }
	    ~B() { delete x; }
	    double getx() { return *x; }
	    void setx(double X) { *x = X; }
	};

These both have a similar interface except that one has a destructor and the
other doesn't. Allocate an array of each:

	A *pa = new A[100];
	B *pb = new B[100];

Now let's consider the ramifications of deleting these two arrays using

	delete [100] pa;	or	delete [] pa;
	delete [100] pb;	or	delete [] pb;

and

	delete pa;
	delete pb;

    o	delete [100] pa;	or	delete [] pa;

	There is no destructor for objects of type A, so the pointer to the
	memory is passed to the global delete operator, ::delete().

    o	delete pa;

	Hmmm, the same thing, the pointer to the memory is passed to
	::delete(). Here's a class where it didn't make a difference.

    o	delete [100] pb;	or	delete [] pb;

	There is a destructor, so ~B() is called for each of the elements
	pb[0] through pb[99]. Then the pointer to the memory is passed to
	::delete().

    o	delete pb;

	Hmmm, there is a destructor, so ~B() is called for *pb. And then
	the pointer to the memory is passed to ::delete(). But what about
	pb[1] through pb[99]? They won't be cleaned up at all!

Now let's consider adding class-specific memory allocation to A and B.

	class A {
	    double x;
	public:
	    A() { x = 3; }
	    double getx() { return x; }
	    void setx(double X) { x = X; }
	    void *operator new(size_t);
	    void operator delete(void*);
	};

	class B {
	    double *x;
	public:
	    B() { x = new double; *x = 3; }
	    ~B() { delete x; }
	    double getx() { return *x; }
	    void setx(double X) { *x = X; }
	    void *operator new(size_t);
	    void operator delete(void*);
	};

Note that class-specific allocators are called for allocating single objects
of a class. However, arrays of objects are still allocated using the global
allocator. Now let's look at calling delete:

    o	delete [100] pa;	or	delete [] pa;

	As before, there is no destructor for objects of type A, so the
	pointer to the memory is passed to the global delete operator,
	::delete().

    o	delete pa;

	Hmmm, now the pointer to the memory is passed to A::delete() instead
	of ::delete() even though it was allocated using ::new() instead of
	A::new(). What happens now is totally unknown.

    o	delete [100] pb;	or	delete [] pb;

	As before, there is a destructor, so ~B() is called for each of the
	elements pb[0] through pb[99]. Then the pointer to the memory is
	passed to ::delete().

    o	delete pb;

	~B() is called for *pb and then B::delete() is called. As before,
	~B() won't be called for pb[1] through pb[99]. That's two strikes
	against this one!

As you can see, the use of "delete x" instead of "delete [] x" is only valid
for a vector when the vector that x is pointing to is for a class which does
not have a destructor or allocation operators. Given that a class designer
should be able to add or delete destructors without affecting the semantics
of the program, clearly one should NEVER attempt to delete a vector without
the "delete[]" syntax.

The ONLY place you're safe in omitting the [] is when deleting a vector of
the built in types, such as int's or double's. It's guaranteed that those
types will NOT have destructors or allocators.

Now let's talk a little bit more about that number which goes within the
brackets of "delete[]". It was decided that the programmer has enough to
worry about without having to worry about keeping track of the number of
elements within the vector. So it was decided that the allocation
environment should keep track of the number for you and the number itself
was declared redundant. In standards parlance, "the feature was deprecated,"
that is, the number is allowed but don't expect future versions of the
language to permit it. Note that only very recent compilers, such as AT&T's
2.1 cfront, implement this language feature.

<<< I don't know what delete [] m means.
<< As I said, your reference is outdated. The latest C++ rules say that the
<< number within the [] is unnecessary and the environment is required to
<< keep track of how many elements are in the array.
< Isn't this a contradiction of the previous statement?  If the environment
< is keeping track of how many elements are in the array, then doesn't it
< know that the variable names an array?

Perhaps it could, or even should, but the answer is no, the environment is
only required to be queried for the size of the array when the objects are
deleted via the "delete[]x" syntax, not for the "delete x" syntax.

					Tony Hansen
				att!pegasus!hansen, attmail!tony
				    hansen@pegasus.att.com

ssr@taylor.Princeton.EDU (Steve S. Roy) (08/01/90)

In article <4942@pegasus.ATT.COM> hansen@pegasus.ATT.COM (Tony L. Hansen) writes:
>
>    "X *x = new X[m]" means to allocate an array of objects of type X, using
>    only the global operator ::new(), invoke the appropriate constructor for
>    x[0] through x[m-1], and assign a pointer to the array to the pointer x.
>    The 1990 definition of C++ also mandates that the C++ environment
>    remember the value m associated with that pointer.
>

Sorry, but I don't have docs for 2.1 available.  Is there any way for
me to get at the size of that array without remembering it thru my
code?  That way I could, say, iterate over all elements of the array
without having a stupid variable like n_x around.

Steve

hansen@pegasus.ATT.COM (Tony L. Hansen) (08/03/90)

< From: ssr@taylor.Princeton.EDU (Steve S. Roy)
< In article <4942@pegasus.ATT.COM> hansen@pegasus.ATT.COM (Tony L. Hansen) writes:
<< "X *x = new X[m]" means to allocate an array of objects of type X, using
<< only the global operator ::new(), invoke the appropriate constructor for
<< x[0] through x[m-1], and assign a pointer to the array to the pointer x.
<< The 1990 definition of C++ also mandates that the C++ environment
<< remember the value m associated with that pointer.
<
< Sorry, but I don't have docs for 2.1 available.  Is there any way for me
< to get at the size of that array without remembering it thru my code?
< That way I could, say, iterate over all elements of the array without
< having a stupid variable like n_x around.

I don't believe that there's such a requirement at this time. An
implementation is free to provide a method of accessing that number, but I
don't think that 2.1 does. Sorry.

You can always propose such a requirement within comp.std.c++.

					Tony Hansen
				att!pegasus!hansen, attmail!tony
				    hansen@pegasus.att.com

davidm@uunet.UU.NET (David S. Masterson) (08/03/90)

Whoa!  What a reply (certainly made things a lot more clearer for me).

Of course, my question was not meant to argue language definition (you're far
more versed in it than I ;-).  On the contrary, my question was more of a
should it be this way.  I think you got both sides of it, though, which was
good.  :-)

However, I have a few more questions...

In article <4942@pegasus.ATT.COM> hansen@pegasus.ATT.COM (Tony L. Hansen)
writes:
>Let's start at the beginning and work forward.
>
>    "X *x = new X" means to allocate an object of type X, using either
>    operator X::new() or the global operator ::new(), invoke the appropriate
>    constructor for that object, and assign a pointer to it to the pointer
>    x.
>
>    "X *x = new X[m]" means to allocate an array of objects of type X, using
>    only the global operator ::new(), invoke the appropriate constructor for
>    x[0] through x[m-1], and assign a pointer to the array to the pointer x.
>    The 1990 definition of C++ also mandates that the C++ environment
>    remember the value m associated with that pointer.

Hmmmm.  If someone had developed X for an embedded system such that X.new()
allocates space for X in a special memory area, then X could never "validly"
be used in an array form because "new X[m]" would cause it to be allocated in
standard memory.  Does anyone see a problem with this?

>    "delete x" means to take the single object (of type X) that x points to
>    and invoke ~X() followed by either operator X::delete() or the global
>    operator ::delete().
>
>    "delete [m] x" means to take the pointer that x points to, treat it as
>    an array, invoke ~X() on x[0] through x[m-1], and then invoke the global
>    operator ::delete(). This syntax is part of all versions of C++ from
>    1985 through 1990. As of 1990, the syntax is deprecated, meaning that it
>    will go away at some point.
>
>    "delete [] x" means to take the pointer that x points to, treat it as an
>    array, invoke ~X() on x[0] through x[m-1], where m is the number that was
>    saved away by operator ::new when the array was allocated, and then
>    invoke the global operator ::delete(). This syntax is part of the 1990
>    definition of C++. Some compilers, in particular AT&T 2.1 cfront,
>    support this syntax. The 2.1 cfront ignores any value passed within the
>    [], just giving a warning message indicating that it is doing so.
>    Note that the compiler is only supposed to look up the number if it is
>    told that the pointer is pointing to an array by using the [] in
>    "delete[] x". It does not look up the number for "delete x".

Here too, if X only points to special memory, then everything is fine, but if
X was supposed to totally reside in a special area, then X could not be
allocated as an array.  Does anyone see a problem with this?

In both cases, it may be a non-problem.  I guess its just a quirk of the
language and people program around it by never writing their classes such that
they are supposed to wholly reside in special areas but rather point to pieces
that are special.  Programmers may even be doing this without realizing the
other side of the coin (thus its a non-problem).

By the way, it is true that the delete() operator (global or class specific)
is called automatically after the destructor, right?  (I'm still working with
a V1.2 compiler)  By this, I mean that there isn't a need to have the
destructor call delete()?  (Your later example confused me slightly on this.) 

><<< I don't know what delete [] m means.
><< As I said, your reference is outdated. The latest C++ rules say that the
><< number within the [] is unnecessary and the environment is required to
><< keep track of how many elements are in the array.
>< Isn't this a contradiction of the previous statement?  If the environment
>< is keeping track of how many elements are in the array, then doesn't it
>< know that the variable names an array?
>
>Perhaps it could, or even should, but the answer is no, the environment is
>only required to be queried for the size of the array when the objects are
>deleted via the "delete[]x" syntax, not for the "delete x" syntax.

Is this "size of the array" in the compiler's environment (in other words,
determined at compile time) or in the run-time environment (in other words,
somehow tacked onto the memory that is allocated)?  There must be plusses and
minusses with either way.
--
===================================================================
David Masterson					Consilium, Inc.
uunet!cimshop!davidm				Mt. View, CA  94043
===================================================================
"If someone thinks they know what I said, then I didn't say it!"

hansen@pegasus.ATT.COM (Tony L. Hansen) (08/05/90)

< From: cimshop!davidm@uunet.UU.NET (David S. Masterson)
< Hmmmm.  If someone had developed X for an embedded system such that
< X.new() allocates space for X in a special memory area, then X could never
< "validly" be used in an array form because "new X[m]" would cause it to be
< allocated in standard memory.  Does anyone see a problem with this?
<
< Here too, if X only points to special memory, then everything is fine, but
< if X was supposed to totally reside in a special area, then X could not be
< allocated as an array.  Does anyone see a problem with this?

If you're developing such a class, then you do indeed have to be aware of
the ins and outs of arrays. Be careful when you play around with "special
memory segments"!

< By the way, it is true that the delete() operator (global or class
< specific) is called automatically after the destructor, right?  (I'm still
< working with a V1.2 compiler)  By this, I mean that there isn't a need to
< have the destructor call delete()?  (Your later example confused me
< slightly on this.) 

Sorry, I didn't mean to cause confusion. :-)

You're correct: one of operator X::delete() or ::delete() IS called
automatically after the destructor (~X()) when the variable is passed to the
delete operator.

Just to throw in another monkey wrench, it is possible to explicitly call
X::~X() for an allocated variable; this is sometimes necessary when dealing
with those "special memory segments" mentioned above. (This feature was
introduced in the 1989 definition of the language, a.k.a. 2.0.)

< Is this "size of the array" in the compiler's environment (in other words,
< determined at compile time) or in the run-time environment (in other
< words, somehow tacked onto the memory that is allocated)?  There must be
< plusses and minusses with either way.

It's "typically" implemented using a run time tracking. (How do you define
"typical" when very few compilers implement the feature? :-) ) I suppose it
WOULD be possible for an implementation to keep track at compile time for
SOME arrays, but that would be a matter of "quality of implementation" and
is not a language issue.

					Tony Hansen
				att!pegasus!hansen, attmail!tony
				    hansen@pegasus.att.com

kearns@cs.columbia.edu (Steve Kearns) (08/06/90)

Re the conflict between "delete [] foo" and "delete foo":

The "right" way, of course, is for C++ to support the "Array of" type
constructor.  While this would require updating lots of existing code
(mainly, changing "fooType * f" to "fooType[] * f"), it would
eliminate a problem with C: the double role of pointers to objects and
pointers to arrays of objects.

Of course, any change that requires updating lots of code is unacceptable;
but I for one am looking forward to the day when D++ is available,
and we can shed all of these C bletcherisms and C++ complexities.

-steve

davidm@uunet.UU.NET (David S. Masterson) (08/07/90)

In article <4956@pegasus.ATT.COM> hansen@pegasus.ATT.COM (Tony L. Hansen) 
writes:

   < From: cimshop!davidm@uunet.UU.NET (David S. Masterson)
   < Hmmmm.  If someone had developed X for an embedded system such that
   < X.new() allocates space for X in a special memory area, then X could never
   < "validly" be used in an array form because "new X[m]" would cause it to be
   < allocated in standard memory.  Does anyone see a problem with this?

   If you're developing such a class, then you do indeed have to be aware of
   the ins and outs of arrays. Be careful when you play around with "special
   memory segments"!

You didn't answer the question !-)  Perhaps you missed the point of the
question (nah! ;-).  Obviously, by the current definition of the language,
there are some gotchas with the scenario above, but the question is should
those gotchas exist?  Why?

   Just to throw in another monkey wrench, it is possible to explicitly call
   X::~X() for an allocated variable; this is sometimes necessary when dealing
   with those "special memory segments" mentioned above. (This feature was
   introduced in the 1989 definition of the language, a.k.a. 2.0.)

Is this a trick to deal with the above?  Should a language consider a special
trick for not too-special cases a language "feature"?  Wait a sec (looking at
above a little more cross-eyed), how would the explicit call to X::~X() work
for this case??

   < There must be plusses and minusses with either way.
   <		[of tracking array sizes]

   								I suppose it
   WOULD be possible for an implementation to keep track at compile time for
   SOME arrays, but that would be a matter of "quality of implementation" and
   is not a language issue.

Why SOME arrays?  The information is there at compile time for all arrays,
isn't it?  (NOTE: I didn't say pointers to arrays.)  I think the "quality"
belongs more in the definition of the language than the implementation.
--
===================================================================
David Masterson					Consilium, Inc.
uunet!cimshop!davidm				Mt. View, CA  94043
===================================================================
"If someone thinks they know what I said, then I didn't say it!"

hansen@pegasus.ATT.COM (Tony L. Hansen) (08/07/90)

<From: cimshop!davidm@uunet.UU.NET (David S. Masterson)
<<In article <4956@pegasus.ATT.COM> hansen@pegasus.ATT.COM (Tony L. Hansen) 
writes:
<<< From: cimshop!davidm@uunet.UU.NET (David S. Masterson) Hmmmm.  If
<<< someone had developed X for an embedded system such that X.new()
<<< allocates space for X in a special memory area, then X could never
<<< "validly" be used in an array form because "new X[m]" would cause it to
<<< be allocated in standard memory. Does anyone see a problem with this?
<<
<< If you're developing such a class, then you do indeed have to be aware of
<< the ins and outs of arrays. Be careful when you play around with "special
<< memory segments"!
<
< You didn't answer the question !-)  Perhaps you missed the point of the
< question (nah! ;-).  Obviously, by the current definition of the language,
< there are some gotchas with the scenario above, but the question is should
< those gotchas exist?  Why?

There really are two ways of looking at the original question above: from
the point of view of someone who wishes to use a particular language feature
and needs to know the ins and outs for doing so, and from the point of view
of someone who wishes to pick on the language itself. Since this discussion
started out in the context of the first set of people, my response above was
aimed at that set.

YES, it is reasonable to consider enhancements to the current definition
such that allocation of arrays could be better managed for use in "special
memory segments". Start up a discussion in comp.std.c++ if you wish to
discuss such extensions.

<< Just to throw in another monkey wrench, it is possible to explicitly call
<< X::~X() for an allocated variable; this is sometimes necessary when
<< dealing with those "special memory segments" mentioned above. (This
<< feature was introduced in the 1989 definition of the language, a.k.a.
<< 2.0.)
<
< Is this a trick to deal with the above?  Should a language consider a
< special trick for not too-special cases a language "feature"?  Wait a sec
< (looking at above a little more cross-eyed), how would the explicit call
< to X::~X() work for this case??

The availability of X::~X() permits a function to destruct an object without
it invoking X::delete() or ::delete(). This is particularly useful for a
class whose objects have been allocated using "alternate" allocation
schemes, such as when using X::new() with extra arguments.

<<< There must be plusses and minusses with either way.
<<<		[of tracking array sizes]
<<   								I suppose it
<< WOULD be possible for an implementation to keep track at compile time for
<< SOME arrays, but that would be a matter of "quality of implementation" and
<< is not a language issue.
<
< Why SOME arrays?  The information is there at compile time for all arrays,
< isn't it?  (NOTE: I didn't say pointers to arrays.)  I think the "quality"
< belongs more in the definition of the language than the implementation.

No, the information is NOT there at compile time for all arrays that get
passed to ::delete(). When you use ::new() to allocate an array, you get a
pointer back. If you pass that pointer on to another function which winds up
doing the delete[], HOW is that function going to know the number of
elements to delete? For this case you HAVE to have run time information.
Whether that size information is passed via a tagged pointer, or the size
info is kept in a separate table, or the size info is kept in the heap arena
next to the object itself, or wherever, the info can only be accessed at run
time in order to delete the array.

					Tony Hansen
				att!pegasus!hansen, attmail!tony
				    hansen@pegasus.att.com