Topic: Operator new Question


Author: rameshs@ix.netcom.com (Ramesh Seshadri )
Date: 1995/08/06
Raw View
In <3vu2gv$kav@bmtlh10.bnr.ca> John Hickin <hickin@bnr.ca> writes:
>
>I accidently discovered that the following code compiles and executes
using my
>favourite compiler:
>
>#include <iostream.h>
>#include <stddef.h>
>
>void* operator new(unsigned sz,const char*,int)
>{
>  return ::operator new(sz);
>}
>
>struct Foo { Foo(); ~Foo(); };
>
>Foo::Foo()  { cerr << "Foo::Foo[this==" << (void*)this << ']' << endl;
}
>Foo::~Foo() { cerr << "Foo::~Foo[this==" << (void*)this << ']' <<
endl; }
>
>main()
>{
>  Foo* p = new(__FILE__,__LINE__) Foo[ 42 ];
>  delete[] p;
>}
>
>
>
>(1) Is it legal C++?
>(2) If so, what should the behavior be?
>
>In my environment (HP-UX 9.x, C++ A.03.05) the Foo::Foo's are called
but the
>Foo::~Foo's are not called.  If i change new(__FILE__,__LINE__) to
just new the
>destructors get called as expected.
>
>--
>John Hickin      Bell-Northern Research, Montreal, Quebec
>(514) 765-7924   hickin@bnr.ca
>

Yes it is a legal C++ code. And it is supposed to call the overloaded
new one time and the ctor and dtor of the Foo for 42 times. In my
environment (Microsoft Visual C++ 2.0) the same code is working without
any change.

- Ramesh S
rameshs@ix.netcom.com






Author: mueller@garwein.hai.siemens.co.at (Harald M. Mueller)
Date: 1995/08/07
Raw View
In article <3vu7te$ql4@engnews2.Eng.Sun.COM>, clamage@Eng.Sun.COM (Steve Clamage) writes:
|>
|>The results of using "delete" on a pointer value obtained from a placement-
|>new are undefined. Any result is allowed. It is invalid C++, but no
|>diagnostic is required.
|>---
|>Steve Clamage, stephen.clamage@eng.sun.com
|>

Panic! Then you couldn't even write

 T* p2 = new(nothrow()) T; // this is from the draft standard, 18.4.1.1,1
 ...
 delete p2;   // should certainly be ok?!?!?!?!?!?!

Is this really so?

HMMueller

== --------------------------------------------------------------
== Dr. Harald M. Mueller mueller@garwein.hai.siemens.co.at
== Siemens AG Austria  Siemens AG Oesterreich
== PSE EZE TNA1   Erdberger Laende 26
== fax: +43-1-71711-5425 A-1030 Vienna/Austria
== --------------------------------------------------------------








Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/08/07
Raw View
Steve Clamage (clamage@Eng.Sun.COM) wrote:

|> The results of using "delete" on a pointer value obtained from a placement-
|> new are undefined. Any result is allowed. It is invalid C++, but no
|> diagnostic is required.

Can this be true?  I always thought that the results of using delete
were to call the destructors, and then call operator delete().  If the
memory was not obtained by calling operator new( size_t ), then the
results are undefined, but in the example given, the memory was obtained
by the placement new calling operator new( size_t ).

Does this mean that I cannot delete memory obtained by:

 p = new ( nothrow() ) T ;

This would sort of make this version of new useless.
--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle--
                             --Beratung in industrieller Datenverarbeitung





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/08/07
Raw View
In article 2i8@gabi.gabi-soft.fr, kanze@gabi-soft.fr (J. Kanze) writes:
>Steve Clamage (clamage@Eng.Sun.COM) wrote:
>
>|> The results of using "delete" on a pointer value obtained from a placement-
>|> new are undefined. Any result is allowed. It is invalid C++, but no
>|> diagnostic is required.
>
>Can this be true?  I always thought that the results of using delete
>were to call the destructors, and then call operator delete().  If the
>memory was not obtained by calling operator new( size_t ), then the
>results are undefined, but in the example given, the memory was obtained
>by the placement new calling operator new( size_t ).
>
>Does this mean that I cannot delete memory obtained by:
>
> p = new ( nothrow() ) T ;
>
>This would sort of make this version of new useless.

My response was sloppy and superficial. Sorry. Here is the text from the
draft standard:

------------------------------------
5.3.5 Delete [expr.delete]
The delete   expression operator destroys a complete object (1.6) or array created by
a new   expression.
 delete   expression:
  :: opt delete cast   expression
  :: opt delete [ ] cast   expression
The first alternative is for non   array objects, and the second is for arrays.  The
operand shall have a pointer type.  The result has type void. In either alternative,
if the value of the operand of delete is the null pointer the operation has no effect.
Otherwise, in the first alternative (delete object), the value of the operand of
delete shall 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 (1.6) representing a
base class of such an object (10), or an expression of class type with a conversion
function to pointer type (_class.conv,fct_) which yields a pointer to such an object.
If not, the behavior is undefined.  In the second alternative (delete array), the
value of the operand of delete shall be a pointer to an array created by a
new   expression without a new   placement specification.  If not, the behavior is
undefined.
------------------------------------

In the cases in question, the returned pointer refers to an object that was
created by a non-placement "operator new". It was passed along by a
placement version of "operator new", but without alteration. Thus, it must
be safe to delete the pointer (modulo double delete or other pointer errros
of course).

Regarding the "nothrow" version of "operator new", the language in the draft
says the effects are the "same" as for the non-placement version, and gives
semantics that are the same except for behavior on allocation failure.

I think we need to add language about using delete to section
18.4.1  Storage allocation and deallocation [lib.new.delete]
to make it plain that James's example above is valid.
---
Steve Clamage, stephen.clamage@eng.sun.com







Author: John Hickin <hickin@bnr.ca>
Date: 1995/08/04
Raw View
I accidently discovered that the following code compiles and executes using my
favourite compiler:

#include <iostream.h>
#include <stddef.h>

void* operator new(unsigned sz,const char*,int)
{
  return ::operator new(sz);
}

struct Foo { Foo(); ~Foo(); };

Foo::Foo()  { cerr << "Foo::Foo[this==" << (void*)this << ']' << endl; }
Foo::~Foo() { cerr << "Foo::~Foo[this==" << (void*)this << ']' << endl; }

main()
{
  Foo* p = new(__FILE__,__LINE__) Foo[ 42 ];
  delete[] p;
}



(1) Is it legal C++?
(2) If so, what should the behavior be?

In my environment (HP-UX 9.x, C++ A.03.05) the Foo::Foo's are called but the
Foo::~Foo's are not called.  If i change new(__FILE__,__LINE__) to just new the
destructors get called as expected.

--
John Hickin      Bell-Northern Research, Montreal, Quebec
(514) 765-7924   hickin@bnr.ca






Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/08/04
Raw View
In article kav@bmtlh10.bnr.ca, John Hickin <hickin@bnr.ca> writes:
>I accidently discovered that the following code compiles and executes using my
>favourite compiler:
>
>#include <iostream.h>
>#include <stddef.h>
>
>void* operator new(unsigned sz,const char*,int)
>{
>  return ::operator new(sz);
>}
>
>struct Foo { Foo(); ~Foo(); };
>
>Foo::Foo()  { cerr << "Foo::Foo[this==" << (void*)this << ']' << endl; }
>Foo::~Foo() { cerr << "Foo::~Foo[this==" << (void*)this << ']' << endl; }
>
>main()
>{
>  Foo* p = new(__FILE__,__LINE__) Foo[ 42 ];
>  delete[] p;
>}
>
>(1) Is it legal C++?
>(2) If so, what should the behavior be?

The results of using "delete" on a pointer value obtained from a placement-
new are undefined. Any result is allowed. It is invalid C++, but no
diagnostic is required.
---
Steve Clamage, stephen.clamage@eng.sun.com