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