473,388 Members | 1,224 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,388 software developers and data experts.

placement new and delete

LuB
I am constantly creating and destroying a singular object used within
a class I wrote.

To save a bit of time, I am considering using 'placement new'. I guess
we could also debate this decision - but for the sake of this post ...
I'm searching for an answer that assumes said decision.

If I allocate memory in the class declaration:

char buffer[sizeof(ObjectX)];

and use 'placement new' inside of of an instance' method:

pObjectX = new (buffer) ObjectX;

then, when it comes time to clean up, I understand that I must
explicitly invoke the destructor .... but its not clear to me if I
need to use placement delete at all?

pObjectX->~ObjectX();
operator delete (pObjectX_, buffer); // ?????? is this or some
version of this required? or more-safe?

Especially considering, I am just going to create the object again and
again ... and I'm not relinquishing control of the memory space back
to the OS. ctor, dtor, ctor, dtor ... just not sure what delete does
in this case.

I guess I'm just not sure what operator delete (arg1, arg2) does? and
if its required when using placement new.

Thanks in advance,

-Luther

Jun 17 '07 #1
15 4975
On Jun 17, 10:08 pm, LuB <lutherba...@yahoo.comwrote:
I am constantly creating and destroying a singular object used within
a class I wrote.
To save a bit of time, I am considering using 'placement new'. I guess
we could also debate this decision - but for the sake of this post ...
My first question would be: how will it save time?
I'm searching for an answer that assumes said decision.
If I allocate memory in the class declaration:
char buffer[sizeof(ObjectX)];
and use 'placement new' inside of of an instance' method:
pObjectX = new (buffer) ObjectX;
You likely get undefined behavior. You have to do something to
ensure that buffer is correctly aligned.
then, when it comes time to clean up, I understand that I must
explicitly invoke the destructor .... but its not clear to me if I
need to use placement delete at all?
pObjectX->~ObjectX();
operator delete (pObjectX_, buffer); // ?????? is this or some
version of this required? or more-safe?
I'm not sure what you're even trying to do here.
Especially considering, I am just going to create the object again and
again ... and I'm not relinquishing control of the memory space back
to the OS. ctor, dtor, ctor, dtor ... just not sure what delete does
in this case.
If you don't call it, it doesn't do anything.
I guess I'm just not sure what operator delete (arg1, arg2) does?
It gets called if the constructor in a placement new throws an
exception.
and if its required when using placement new.
*If* you have a placement new which actually allocates new
resources, you should provide a corresponding placement delete.
If in a new expression which uses your placement new function,
the constructor of the object exits with an exception, the
compiler will call your placement delete.

That's the only time it can or will be called.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 17 '07 #2
LuB wrote:
I am constantly creating and destroying a singular object used within
a class I wrote.

To save a bit of time, I am considering using 'placement new'. I guess
we could also debate this decision - but for the sake of this post ...
I'm searching for an answer that assumes said decision.
Have you considered giving the object its own new and delete operators?

--
Ian Collins.
Jun 17 '07 #3
LuB wrote:
I am constantly creating and destroying a singular object used within
a class I wrote.

To save a bit of time, I am considering using 'placement new'. I guess
we could also debate this decision - but for the sake of this post ...
I'm searching for an answer that assumes said decision.

If I allocate memory in the class declaration:

char buffer[sizeof(ObjectX)];
Make sure you use the right alignment.
long buffer[ (sizeof(ObjectX)+sizeof(long)-1)/sizeof(long) ];
>
and use 'placement new' inside of of an instance' method:

pObjectX = new (buffer) ObjectX;

then, when it comes time to clean up, I understand that I must
explicitly invoke the destructor .... but its not clear to me if I
need to use placement delete at all?

pObjectX->~ObjectX();
..... that's it - do no more.
operator delete (pObjectX_, buffer); // ?????? is this or some
version of this required? or more-safe?
Don't so this ..
>
Especially considering, I am just going to create the object again and
again ... and I'm not relinquishing control of the memory space back
to the OS. ctor, dtor, ctor, dtor ... just not sure what delete does
in this case.
Whatever it is, it's probably not what you want to do.

I guess I'm just not sure what operator delete (arg1, arg2) does? and
if its required when using placement new.
operator new and operator delete concern themselves with memory allocation.

When using operator now - like so:

new T();

It will allocate memory using operator new and then run the constructor
(like placement new).

Jun 17 '07 #4
Gianni Mariani wrote:
LuB wrote:
>I am constantly creating and destroying a singular object used within
a class I wrote.

To save a bit of time, I am considering using 'placement new'. I guess
we could also debate this decision - but for the sake of this post ...
I'm searching for an answer that assumes said decision.

If I allocate memory in the class declaration:

char buffer[sizeof(ObjectX)];

Make sure you use the right alignment.
long buffer[ (sizeof(ObjectX)+sizeof(long)-1)/sizeof(long) ];
How does that ensure correct alignment?

--
Alan Johnson
Jun 18 '07 #5
On Jun 18, 6:34 am, Alan Johnson <a...@yahoo.comwrote:
Gianni Mariani wrote:
LuB wrote:
I am constantly creating and destroying a singular object used within
a class I wrote.
To save a bit of time, I am considering using 'placement new'. I guess
we could also debate this decision - but for the sake of this post ...
I'm searching for an answer that assumes said decision.
If I allocate memory in the class declaration:
char buffer[sizeof(ObjectX)];
Make sure you use the right alignment.
long buffer[ (sizeof(ObjectX)+sizeof(long)-1)/sizeof(long) ];
How does that ensure correct alignment?
It doesn't, at least not on a Sun Sparc compiling in 32 bit
mode (and probably on a lot of other machines where long is 32
bits, and double 64).

The usual solution is to use a union:

union MaxAlign {
int i ;
long l ;
long double ld ;
double d ;
void* p ;
void (* pf)() ;
MaxAlign* ps ;
} ;
union {
char data[ sizeof( ObjectX ) ] ;
MaxAlign dummyForAlignment ;
} buffer;

new ( buffer.data ) ...

Technically, even that isn't guaranteed by the standard, but in
practice, it should work. (Logically, you shouldn't need double
if you have long double, but I've encountered cases where long
double has an alignment of 4, and double an alignment of 8.)

This may result in allocating too much memory for small types.
There are template meta-programming tricks which can be used to
avoid this, if it is a problem.

--
James Kanze (GABI Software, from CAI) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 18 '07 #6
James Kanze wrote:
>
This may result in allocating too much memory for small types.
There are template meta-programming tricks which can be used to
avoid this, if it is a problem.
Looking forward, the next revision of the standard incorporates TR1's
templates alignment_of and aligned_storage, as well as the alignof
keyword. With TR1, you'd write:

aligned_storage<sizeof(ObjectX),
alignment_of<ObjectX>::value>::type data;
ObjectX *ptr = new(&data) ObjectX;

With C++0x the same thing still works, but you can be a little less
verbose with:

aligned_storage<sizeof(ObjectX), alignof(ObjectX)>::type data;
ObjectX *ptr = new(&data) ObjectX;

or, if you want the compiler to figure out the optimal alignment:

aligned_storage<sizeof(ObjectX)>::type data;
ObjectX *ptr = new(&data) ObjectX;

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Jun 18 '07 #7

"James Kanze" <ja*********@gmail.comwrote in message
news:11*********************@p77g2000hsh.googlegro ups.com...
On Jun 17, 10:08 pm, LuB <lutherba...@yahoo.comwrote:
>*If* you have a placement new which actually allocates new
resources, you should provide a corresponding placement delete.
If in a new expression which uses your placement new function,
the constructor of the object exits with an exception, the
compiler will call your placement delete.
That's the only time it can or will be called.
He'll have to call the delete operator explicitely in his code somewhere to
get any behavior defined in the class's destructor. Use of placement delete
should be used symmetrically with placement new.

John

Jun 18 '07 #8

"LuB" <lu*********@yahoo.comwrote in message
news:11*********************@n60g2000hse.googlegro ups.com...
>I am constantly creating and destroying a singular object used within
a class I wrote.

To save a bit of time, I am considering using 'placement new'. I guess
we could also debate this decision - but for the sake of this post ...
I'm searching for an answer that assumes said decision.

If I allocate memory in the class declaration:

char buffer[sizeof(ObjectX)];

and use 'placement new' inside of of an instance' method:

pObjectX = new (buffer) ObjectX;

then, when it comes time to clean up, I understand that I must
explicitly invoke the destructor .... but its not clear to me if I
need to use placement delete at all?

pObjectX->~ObjectX();
That's explicitely calling the destructor.
operator delete (pObjectX_, buffer); // ?????? is this or some
version of this required?
No.
or more-safe?
Especially considering, I am just going to create the object again and
again ... and I'm not relinquishing control of the memory space back
to the OS. ctor, dtor, ctor, dtor ... just not sure what delete does
in this case.

I guess I'm just not sure what operator delete (arg1, arg2) does? and
if its required when using placement new.
This is placement new's syntax:
pObjectX = new (buffer) ObjectX;
This is placement delete's syntax (Or so, how I categorize it. It's just an
explicit call to the destructor. I'm not sure if the standard actually
defines placement deleta as some internal call or not. Probably. The below
is the companion behavior to placement new.):
pObjectX->~ObjectX();
There's no requirement to overload the class's new and/or delete operators
to use placement syntax.

John

Jun 18 '07 #9
LuB
On Jun 17, 3:20 pm, James Kanze <james.ka...@gmail.comwrote:
On Jun 17, 10:08 pm, LuB <lutherba...@yahoo.comwrote:
I am constantly creating and destroying a singular object used within
a class I wrote.
To save a bit of time, I am considering using 'placement new'. I guess
we could also debate this decision - but for the sake of this post ...

My first question would be: how will it save time?

It doesn't allocate memory. It essentially just returns a pointer.

>
I'm searching for an answer that assumes said decision.
If I allocate memory in the class declaration:

and use 'placement new' inside of of an instance' method:
pObjectX = new (buffer) ObjectX;

You likely get undefined behavior. You have to do something to
ensure that buffer is correctly aligned.
Not sure I follow but then, maybe my example wasn't clear.

struct ObjectX { int x; int y; };

struct UserAnObject
{
char buffer[sizeof(ObjectX)];

void onMouseDown()
{
pObjectX = new (buffer) ObjectX;

// do something here

}

void onCaptureChanged()
{
// finish doing something here

pObjectX->~ObjectX();
operator delete (pObjectX_, buffer);
}

ObjectX* pOBjectX;

};

>
then, when it comes time to clean up, I understand that I must
explicitly invoke the destructor .... but its not clear to me if I
need to use placement delete at all?
pObjectX->~ObjectX();
operator delete (pObjectX_, buffer); // ?????? is this or some
version of this required? or more-safe?

I'm not sure what you're even trying to do here.

See above for clarification.

>
Especially considering, I am just going to create the object again and
again ... and I'm not relinquishing control of the memory space back
to the OS. ctor, dtor, ctor, dtor ... just not sure what delete does
in this case.

If you don't call it, it doesn't do anything.
I guess I'm just not sure what operator delete (arg1, arg2) does?

It gets called if the constructor in a placement new throws an
exception.
and if its required when using placement new.

*If* you have a placement new which actually allocates new
resources,

No. My example does not.

you should provide a corresponding placement delete.
If in a new expression which uses your placement new function,
the constructor of the object exits with an exception, the
compiler will call your placement delete.
Not sure how it will call 'my placement delete' unless you're
referring to a class member. My example does not define a 'placement
delete'. I am wondering if I should invoke the global placement
delete ... (hope that makes sense).
>
That's the only time it can or will be called.
Thanks for your initial input ... hopefully, my comments make things a
little clearer?

Thanks,

-Luther

Jun 19 '07 #10
Pete Becker wrote:
....
or, if you want the compiler to figure out the optimal alignment:

aligned_storage<sizeof(ObjectX)>::type data;
ObjectX *ptr = new(&data) ObjectX;
How does the proposal define "optimal" alignment?
Jun 19 '07 #11
On Jun 19, 1:33 am, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
"James Kanze" <james.ka...@gmail.comwrote in message
news:11*********************@p77g2000hsh.googlegro ups.com...
On Jun 17, 10:08 pm, LuB <lutherba...@yahoo.comwrote:
*If* you have a placement new which actually allocates new
resources, you should provide a corresponding placement delete.
If in a new expression which uses your placement new function,
the constructor of the object exits with an exception, the
compiler will call your placement delete.
That's the only time it can or will be called.
He'll have to call the delete operator explicitely in his code
somewhere to get any behavior defined in the class's
destructor. Use of placement delete should be used
symmetrically with placement new.
[Hey, this one worked. Now I'll have to go back and figure
out where I posted it from:-).]

I'm not too sure what you mean by "call the delete operator
explicitely", but placement new and placement delete are not
symmetrical. Placement new is called by means of a new
expression; there is no way to invoke placement delete by means
of a delete expression, which always uses a non-placement
delete.

The most frequent use of placement delete is when separating
memory management and construction/deletion, in e.g. a container
class. This uses the standard placement delete, the one with
the void* argument. And you never call delete on such objects,
you call the destructor explicitly.

In the case of user defined placement new which do require a
delete, e.g. when the argument is the address of a special
allocator or pool, you also have to redefine the non-placement
operator new and operator delete functions, and arrange somehow
in the non-placement operator delete function to handle the
special cases.

--
James Kanze (GABI Software, from CAI) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 19 '07 #12
On Jun 19, 3:14 am, LuB <lutherba...@yahoo.comwrote:
On Jun 17, 3:20 pm, James Kanze <james.ka...@gmail.comwrote:
On Jun 17, 10:08 pm, LuB <lutherba...@yahoo.comwrote:
I am constantly creating and destroying a singular object used within
a class I wrote.
To save a bit of time, I am considering using 'placement new'. I guess
we could also debate this decision - but for the sake of this post ...
My first question would be: how will it save time?
It doesn't allocate memory. It essentially just returns a pointer.
The memory has to be allocated somehow, in every case. You
can't construct an object without having the memory for it.

I had more or less assumed that the memory would be declared as
as local variable. In which case, the comparison isn't with
non-placement delete, but with just declaring a local instance
of the object.
I'm searching for an answer that assumes said decision.
If I allocate memory in the class declaration:
and use 'placement new' inside of of an instance' method:
pObjectX = new (buffer) ObjectX;
You likely get undefined behavior. You have to do something to
ensure that buffer is correctly aligned.
Not sure I follow
If you've declared buffer as a local (or a static) object:
char buffer[ sizeof( ObjectX ) ] ;
you're not at all guaranteed that it will be correctly aligned
for an ObjectX; on my system, if very often won't be.
but then, maybe my example wasn't clear.
struct ObjectX { int x; int y; };
struct UserAnObject
{
char buffer[sizeof(ObjectX)];
void onMouseDown()
{
pObjectX = new (buffer) ObjectX;
// do something here
}
void onCaptureChanged()
{
// finish doing something here
pObjectX->~ObjectX();
operator delete (pObjectX_, buffer);
}
ObjectX* pOBjectX;
};
And where is UserAnObject declared? In this case (a bit
special), you're garanteed that the buffer has the same address
as the whole object (but only because UserAnObject is a
POD---add a constructor, for example, and you loose the
guarantee), but this doesn't necessarily mean that it is
sufficiently aligned for an ObjectX. Again, on my system, when
compiling in 32 bit mode, the compiler will ensure that all
UserAnObject are aligned on an address multiple of 4, because
this is necessary for the pointer it contains, but if ObjectX
contains a double, it requires an alignment on a multiple of 8.

If UserAnObject in fact contains virtual functions, the compiler
will insert the vptr before "char buffer[]", almost guaranteeing
that it will NOT be correctly aligned for a double if
UserAnObject is dynamically allocated.

Also: you don't really have to call operator delete here. The
standard guarantees that it is a no-op, but in general, if the
operator new called by the new expression doesn't allocate any
resources, you don't need to call operator delete.
then, when it comes time to clean up, I understand that I must
explicitly invoke the destructor .... but its not clear to me if I
need to use placement delete at all?
pObjectX->~ObjectX();
operator delete (pObjectX_, buffer); // ?????? is this or some
version of this required? or more-safe?
I'm not sure what you're even trying to do here.
See above for clarification.
OK. It's not necessary, and it's not usual to see it (although
the standard guarantees that it will work).

[...]
you should provide a corresponding placement delete.
If in a new expression which uses your placement new function,
the constructor of the object exits with an exception, the
compiler will call your placement delete.
Not sure how it will call 'my placement delete' unless you're
referring to a class member. My example does not define a 'placement
delete'. I am wondering if I should invoke the global placement
delete ... (hope that makes sense).
For the standard placement new and delete, there's really never
any reason to call placement delete. For a user defined one,
however...

Consider something like:

union BlockHeader { Allocator* alloc, double forAlignment } ;

void*
operator new( size_t n, Allocator* pAlloc )
{
BlockHeader* p =
static_cast< BlockHeader* >(
pAlloc->alloc( n + sizeof( BlockHeader ) ) ;
if ( p == NULL ) {
throw std::bad_alloc() ;
}
p->alloc = pAlloc ;
return p + 1 ;
}

void*
operator new( size_t n )
{
BlockHeader* p =
static_cast< BlockHeader* >( malloc( n +
sizeof( BlockHeader ) ) ;
if ( p == NULL ) {
throw std::bad_alloc() ;
}
p->alloc = NULL ;
return p + 1 ;
}

void
operator delete( void* userPtr )
{
BlockHeader* p
= static_cast< BlockHeader* >( userPtr ) - 1 ;
if ( p->alloc == NULL ) {
free( p ) ;
} else {
p->alloc->free( p ) ;
}
}

According to the rules, if you do something like:

MyType* p = new ( someAllocator ) MyType ;

and the constructor of MyType exits via an exception, no
operator delete function will be called. If you have a
corresponding placement delete, however, it will be called.
Since in this case, you are actually allocating memory in your
placement new, you should provide a placement delete, so that it
will be called.

--
James Kanze (GABI Software, from CAI) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 19 '07 #13

"James Kanze" <ja*********@gmail.comwrote in message
news:11*********************@m36g2000hse.googlegro ups.com...
On Jun 19, 1:33 am, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
"James Kanze" <james.ka...@gmail.comwrote in message
news:11*********************@p77g2000hsh.googlegro ups.com...
On Jun 17, 10:08 pm, LuB <lutherba...@yahoo.comwrote:
*If* you have a placement new which actually allocates new
resources, you should provide a corresponding placement delete.
If in a new expression which uses your placement new function,
the constructor of the object exits with an exception, the
compiler will call your placement delete.
That's the only time it can or will be called.
He'll have to call the delete operator explicitely in his code
somewhere to get any behavior defined in the class's
destructor. Use of placement delete should be used
symmetrically with placement new.
" [Hey, this one worked. Now I'll have to go back and figure
out where I posted it from:-).]"

(No it didn't. Because the post was so short, I put the '>' symbols in by
hand. Notice they're missing the usual space after the symbols.)

"I'm not too sure what you mean by "call the delete operator
explicitely",

SomeClassObjectPtr->~SomeClassObject()

" but placement new and placement delete are not
symmetrical. Placement new is called by means of a new
expression; there is no way to invoke placement delete by means
of a delete expression, which always uses a non-placement
delete."

I'm probably using the terminology "placement delete" wrong. But it would
seem fitting in my context because placement new is object construction and
the above explicit call of the class delete is object destruction. I
understand that there is a delete operator with a void* argument hidden
somewhere (internal to the compiler?). Why object construction was
obfuscated in the placement new syntax befuddles me.

"The most frequent use of placement delete is when separating
memory management and construction/deletion, in e.g. a container
class. This uses the standard placement delete, the one with
the void* argument. And you never call delete on such objects,
you call the destructor explicitly."

Define "standard placement delete" please.

"In the case of user defined placement new which do require a
delete, e.g. when the argument is the address of a special
allocator or pool, you also have to redefine the non-placement
operator new and operator delete functions, and arrange somehow
in the non-placement operator delete function to handle the
special cases."

Define "user defined placement new" please. I don't understand how that can
be useful. So it can be redefined? What good would that do since the
mechanics of calling constructors is not exposed? When I think of placement
new, I think of the syntax that engages the behavior (construction), not the
actual implementation of placement new.

John
Jun 19 '07 #14
LuB
On Jun 19, 4:09 am, James Kanze <james.ka...@gmail.comwrote:
On Jun 19, 3:14 am, LuB <lutherba...@yahoo.comwrote:
On Jun 17, 3:20 pm, James Kanze <james.ka...@gmail.comwrote:
On Jun 17, 10:08 pm, LuB <lutherba...@yahoo.comwrote:
I am constantly creating and destroying a singular object used within
a class I wrote.
To save a bit of time, I am considering using 'placement new'. I guess
we could also debate this decision - but for the sake of this post ...
My first question would be: how will it save time?
It doesn't allocate memory. It essentially just returns a pointer.

The memory has to be allocated somehow, in every case. You
can't construct an object without having the memory for it.

I had more or less assumed that the memory would be declared as
as local variable. In which case, the comparison isn't with
non-placement delete, but with just declaring a local instance
of the object.
I'm searching for an answer that assumes said decision.
If I allocate memory in the class declaration:
and use 'placement new' inside of of an instance' method:
pObjectX = new (buffer) ObjectX;
You likely get undefined behavior. You have to do something to
ensure that buffer is correctly aligned.
Not sure I follow

If you've declared buffer as a local (or a static) object:
char buffer[ sizeof( ObjectX ) ] ;
you're not at all guaranteed that it will be correctly aligned
for an ObjectX; on my system, if very often won't be.
but then, maybe my example wasn't clear.
struct ObjectX { int x; int y; };
struct UserAnObject
{
char buffer[sizeof(ObjectX)];
void onMouseDown()
{
pObjectX = new (buffer) ObjectX;
// do something here
}
void onCaptureChanged()
{
// finish doing something here
pObjectX->~ObjectX();
operator delete (pObjectX_, buffer);
}
ObjectX* pOBjectX;
};

And where is UserAnObject declared? In this case (a bit
special), you're garanteed that the buffer has the same address
as the whole object (but only because UserAnObject is a
POD---add a constructor, for example, and you loose the
guarantee), but this doesn't necessarily mean that it is
sufficiently aligned for an ObjectX. Again, on my system, when
compiling in 32 bit mode, the compiler will ensure that all
UserAnObject are aligned on an address multiple of 4, because
this is necessary for the pointer it contains, but if ObjectX
contains a double, it requires an alignment on a multiple of 8.

If UserAnObject in fact contains virtual functions, the compiler
will insert the vptr before "char buffer[]", almost guaranteeing
that it will NOT be correctly aligned for a double if
UserAnObject is dynamically allocated.

Also: you don't really have to call operator delete here. The
standard guarantees that it is a no-op, but in general, if the
operator new called by the new expression doesn't allocate any
resources, you don't need to call operator delete.
then, when it comes time to clean up, I understand that I must
explicitly invoke the destructor .... but its not clear to me if I
need to use placement delete at all?
pObjectX->~ObjectX();
operator delete (pObjectX_, buffer); // ?????? is this or some
version of this required? or more-safe?
I'm not sure what you're even trying to do here.
See above for clarification.

OK. It's not necessary, and it's not usual to see it (although
the standard guarantees that it will work).

[...]
you should provide a corresponding placement delete.
If in a new expression which uses your placement new function,
the constructor of the object exits with an exception, the
compiler will call your placement delete.
Not sure how it will call 'my placement delete' unless you're
referring to a class member. My example does not define a 'placement
delete'. I am wondering if I should invoke the global placement
delete ... (hope that makes sense).

For the standard placement new and delete, there's really never
any reason to call placement delete. For a user defined one,
however...

Consider something like:

union BlockHeader { Allocator* alloc, double forAlignment } ;

void*
operator new( size_t n, Allocator* pAlloc )
{
BlockHeader* p =
static_cast< BlockHeader* >(
pAlloc->alloc( n + sizeof( BlockHeader ) ) ;
if ( p == NULL ) {
throw std::bad_alloc() ;
}
p->alloc = pAlloc ;
return p + 1 ;
}

void*
operator new( size_t n )
{
BlockHeader* p =
static_cast< BlockHeader* >( malloc( n +
sizeof( BlockHeader ) ) ;
if ( p == NULL ) {
throw std::bad_alloc() ;
}
p->alloc = NULL ;
return p + 1 ;
}

void
operator delete( void* userPtr )
{
BlockHeader* p
= static_cast< BlockHeader* >( userPtr ) - 1 ;
if ( p->alloc == NULL ) {
free( p ) ;
} else {
p->alloc->free( p ) ;
}
}

According to the rules, if you do something like:

MyType* p = new ( someAllocator ) MyType ;

and the constructor of MyType exits via an exception, no
operator delete function will be called. If you have a
corresponding placement delete, however, it will be called.
Since in this case, you are actually allocating memory in your
placement new, you should provide a placement delete, so that it
will be called.
Thanks for the extended response. Everyone's responses have been quite
helpful.

So I'm taking a step back. Many people avoid certain idioms like the
plague ... such as using memset as a fast, cheap way to copy entire
objects, etc. It just opens up lots of potentially unwanted behavior
or conditions.

So - on a slightly deeper or higher level, what about this 'approach'?
We've talked about explicitly invoking the delete operator - but
underneath that ... is placement new a good option in this situation?

I could change the object architecture a little bit -- and edit my
class to have build and destroy functionality in methods ... instead
of ctor and dtor pairs - and I could just allocate said object with
the instance ... and explicitly objectX.build(...) and
objectX.destroy(...) the same object over and over again ... if that
approach would be better than using placement new.

I guess, I understand that I can't guarantee alignment ... and, I know
that were I writing Assembly, that means I'd have to go out of my way
to read the data ... but what does that mean in a normal compiler? I
thought the compiler would hide things like that from me. Does it mean
things will be slower than optimal? or does that mean things will
break? or does that mean things are undefined on different OSs or with
different compilers? Admittedly, its not a commonly used idiom (I
guess) and while I guess things like alignment might not be guaranteed
- I'm not sure what that means - in terms of "Go For It" ... but
realize it'll be problematic ..? or stay away from it - since you open
a bag of worms.

I didn't hear alot of negative reaction ... but then again, we were
focussed on the need to explicitly invoke the delete operator or not.
It seems like a good approach ... Allows me to Initialize in ctor and
Destroy in dtor (traditional OO) -- and its only one object (easy to
manage) ... so 'new' and 'delete' work well in general for my
situation ... but this idea of placement new ... is it really a good
optimization in this context?

For what its worth, the implementation doesn't really _have_ to be
portable. It is part of a proprietary windowing system ... but I'd
like it to be relatively safe, predictable, reliable and faster than
constantly allocating and releasing memory to the OS many times.

Thanks to all,

-Luther

Jun 20 '07 #15
On Jun 20, 5:44 am, LuB <lutherba...@yahoo.comwrote:

[...]
So I'm taking a step back. Many people avoid certain idioms like the
plague ... such as using memset as a fast, cheap way to copy entire
objects, etc. It just opens up lots of potentially unwanted behavior
or conditions.
So - on a slightly deeper or higher level, what about this 'approach'?
We've talked about explicitly invoking the delete operator - but
underneath that ... is placement new a good option in this situation?
Maybe. Over all, I'd probably favor a pointer and classical
new, until the profiler said that allocation really was a
bottleneck. It has the advantage of being a simple, easy to
understand way of doing things.
I could change the object architecture a little bit -- and edit my
class to have build and destroy functionality in methods ... instead
of ctor and dtor pairs - and I could just allocate said object with
the instance ... and explicitly objectX.build(...) and
objectX.destroy(...) the same object over and over again ... if that
approach would be better than using placement new.
If you're always building the same type, just adding a
reinitialize function to it would seem to be the best solution.
I guess, I understand that I can't guarantee alignment ... and, I know
that were I writing Assembly, that means I'd have to go out of my way
to read the data ... but what does that mean in a normal compiler? I
thought the compiler would hide things like that from me.
It does when it knows about them. If you declare an ObjectX,
the compiler will assure that it is adequately aligned. The
problem here is that you are declaring a char[]; the compiler
will ensure that it is adequately aligned for a char[], but that
might not be enough for an ObjectX.
Does it mean
things will be slower than optimal? or does that mean things will
break? or does that mean things are undefined on different OSs or with
different compilers?
It's basically undefined or unspecified behavior. On an Intel
architecture, it means that things will be slower. On a Sparc
(and most other architectures I've seen), it means that the
program will core dump. It's quite possible that on some
architecture, you simply get wrong values, or end up modifying
something outside the object when you meant to change a value in
the object.
Admittedly, its not a commonly used idiom (I
guess) and while I guess things like alignment might not be guaranteed
- I'm not sure what that means - in terms of "Go For It" ... but
realize it'll be problematic ..? or stay away from it - since you open
a bag of worms.
You open a bag of worms. I've done similar things once or twice
in the past, when the profiler said they were needed, but you
generally have to be very, very careful.
I didn't hear alot of negative reaction ... but then again, we were
focussed on the need to explicitly invoke the delete operator or not.
It seems like a good approach ... Allows me to Initialize in ctor and
Destroy in dtor (traditional OO) -- and its only one object (easy to
manage) ... so 'new' and 'delete' work well in general for my
situation ... but this idea of placement new ... is it really a good
optimization in this context?
If you take the necessary steps to ensure correct alignment,
there's no reason why it can't be made to work. As I said, I've
done so in the past. But it is additional complexity for
nothing unless you really need it.
For what its worth, the implementation doesn't really _have_ to be
portable. It is part of a proprietary windowing system ... but I'd
like it to be relatively safe, predictable, reliable and faster than
constantly allocating and releasing memory to the OS many times.
Operator delete doesn't necessarily (or even usually) release
memory to the OS. Most of the time, it allocates from and frees
to an arena which it maintains itself, only going to the OS when
it doesn't have enough memory otherwise. If you're dealing with
fixed size objects, it's also fairly simple to implement your
own allocator, to reuse the previously deleted object.

--
James Kanze (GABI Software, from CAI) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 20 '07 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

23
by: Giancarlo Niccolai | last post by:
Hello all. I have peeked through the FAQ and all relevant links, and also through Stroustrup book, but I have not been able to find an answer, so I have to post here as a last resort. It...
20
by: Ioannis Vranos | last post by:
When we use the standard placement new operator provided in <new>, and not a definition of owr own, isn't a call to placement delete enough? Consider the code: #include <new>
8
by: elviin | last post by:
Hello. I tried a sample programm using placement new. I am not sure if i understand this technique correctly. I do not mean usage but a real world application. Could anyone to describe some...
2
by: XHengDF | last post by:
something like this: T *p = new(Alloc&)T; delete(Alloc&) p; is that will take problems! now we could use Dealloc(Alloc&, void *p); in the bs's tech Faq, i could not find the reason why not take...
1
by: SarahT | last post by:
Hi folks, I am doing something Very Bad and Wrong (which I'll spare you the details of) that requires overloading new for some specific classes. So, for example: class MyWeirdThingy {...
9
by: karthikbalaguru | last post by:
Hi, I find that articles stating that 'placement new' constructs an object on a pre-allocated buffer and so takes less time. Actually, we have to consider the allocation of the buffer and then...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.