C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

why isn't there a placement delete syntax

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
andrew_nuss@yahoo.com
Guest





PostPosted: Tue Sep 26, 2006 8:05 pm    Post subject: why isn't there a placement delete syntax Reply with quote



Hi,

I have created an interface with placement new that uses a Heap
reference that supplies Alloc/Free functionality. The compiler forces
the definition of a placement delete. But there is no syntax that I
can find to invoke the placement delete!

struct Object {
static void* operator new (Heap&, size_t);
static void operator delete (Heap&, void*);
};

class MyObj : public Object {
...
};

main {
Heap heap;
MyObj* p = new (heap) MyObj(); // works!
delete (heap) p; // illlegal!
}

Can anyone explain how to delete these objects. I.e. why doesn't the
obvious analagous invocation of delete work using placement syntax.
What do I do?

Andy


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Alberto Ganesh Barbati
Guest





PostPosted: Tue Sep 26, 2006 11:21 pm    Post subject: Re: why isn't there a placement delete syntax Reply with quote



andrew_nuss (AT) yahoo (DOT) com ha scritto:
Quote:
struct Object {
static void* operator new (Heap&, size_t);
static void operator delete (Heap&, void*);
};

class MyObj : public Object {
...
};

main {
Heap heap;
MyObj* p = new (heap) MyObj(); // works!
delete (heap) p; // illlegal!
}

Can anyone explain how to delete these objects. I.e. why doesn't the
obvious analagous invocation of delete work using placement syntax.

I believe a placement delete syntax has not been provided because it
could be too error-prone. It would be too easy to make the mistake of
invoking delete with a parameter value different from that used for new.

Quote:
What do I do?

Placement new is expected to store the additional info somewhere, in
particular in a place where operator delete can obtain it using the only
information it has, i.e.: the pointer. The most obvious way is to store
the info in block itself, as in (alignment issues omitted for brevity):

void* operator new (Heap& h, size_t n)
{
// alloc some more space to hold the extra info
void* ptr = h.alloc(n + sizeof(Heap*));
Heap* hptr = static_cast<Heap*>(ptr);
*hptr = &h; // store info in the block
return hptr + 1;
}

// placement delete used only when the constructor throws
void operator delete (Heap& h, void* ptr)
{
Heap* hptr = static_cast<Heap*>(ptr);
h.free(hptr - 1);
}

// regular delete, not placement!
void operator delete (void* ptr)
{
Heap* hptr = static_cast<Heap*>(ptr);
hptr[-1]->free(hptr - 1); // retrieve info from the block
}

You may have other ways to determine the heap, for example you can keep
a map pointers/heap. A real life example is an embedded platform that
has two different kind of memory, for example a "fast" and a "slow"
memory. The placement new syntax could be used to let the user select
which kind of memory to allocate from. If the address ranges of the two
kind of memories do not overlap, the delete operator can quickly
determine which kind of memory to deallocate from by just looking at the
address.

If you start feeling discomfort about the placement syntax, it's
perfectly normal. It will pass. ;-)

Regards,

Ganesh

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
andrew_nuss@yahoo.com
Guest





PostPosted: Wed Sep 27, 2006 3:00 am    Post subject: Re: why isn't there a placement delete syntax Reply with quote



Alberto Ganesh Barbati wrote:
Quote:

void* operator new (Heap& h, size_t n)
{
// alloc some more space to hold the extra info
void* ptr = h.alloc(n + sizeof(Heap*));
Heap* hptr = static_cast<Heap*>(ptr);
*hptr = &h; // store info in the block
return hptr + 1;
}


I like this solution but I do have a question. Will it fail on some
platforms with tricky alignment issues because the sizeof(Heap*) header
leaves the logical void* addr returned on an unaligned boundary? Or is
sizeof(Heap*) always on an alignment boundary, even for doubles?


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Alberto Ganesh Barbati
Guest





PostPosted: Wed Sep 27, 2006 10:59 pm    Post subject: Re: why isn't there a placement delete syntax Reply with quote

kanze ha scritto:
Quote:
Alberto Ganesh Barbati wrote:
andrew_nuss (AT) yahoo (DOT) com ha scritto:
struct Object {
static void* operator new (Heap&, size_t);
static void operator delete (Heap&, void*);
};

Placement new is expected to store the additional info
somewhere, in particular in a place where operator delete can
obtain it using the only information it has, i.e.: the
pointer.

Note that this means that you cannot define a placement new
requiring a delete without also replacing global new and delete.
You have to replace global delete, since this is the delete
which will be called even for the objects allocated by placement
new. And you have to replace global new, because global new has
to work with global delete (and there's no way for your new
global delete to access the global delete it is replacing).

We are talking about per-class allocation and deallocation functions, so
global new/delete are not involved.

Quote:
The most obvious way is to store the info in block itself, as
in (alignment issues omitted for brevity):

void* operator new (Heap& h, size_t n)
{
// alloc some more space to hold the extra info
void* ptr = h.alloc(n + sizeof(Heap*));
Heap* hptr = static_cast<Heap*>(ptr);
*hptr = &h; // store info in the block
return hptr + 1;
}

// placement delete used only when the constructor throws
void operator delete (Heap& h, void* ptr)
{
Heap* hptr = static_cast<Heap*>(ptr);
h.free(hptr - 1);
}

// regular delete, not placement!
void operator delete (void* ptr)
{
Heap* hptr = static_cast<Heap*>(ptr);
hptr[-1]->free(hptr - 1); // retrieve info from the block
}

And what happens when this delete is called for an object
allocated with non placement operator new?

That case can never occur because the class has a placement operator new
that inhibits the use of the non-placement syntax:

struct Object
{
static void* operator new(size_t n, Heap& h);
static void operator delete(void* p, Heap& h);
static void operator delete(void* p);
};

int main()
{
Object* o = new Object; // ill-formed
}

Ganesh

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Alberto Ganesh Barbati
Guest





PostPosted: Thu Sep 28, 2006 5:46 am    Post subject: Re: why isn't there a placement delete syntax Reply with quote

Ulrich Eckhardt ha scritto:
Quote:
Now, placement new only removes the task of allocating storage, the
storage
is already provided. Similarly, you only invoke the destructor lateron
instead of calling delete because the memory management is left out.

The syntax for those steps is

char buffer[sizeof (X)];

X* x = new (buffer) X;
x->~X();


This is correct, but it's a very limited view of the placement new
syntax. Placement new can have any type as parameter (not necessarily a
pointer to uninitialized memory) and can have even more than one parameter.

In fact, the OP was using "new(heap) Object" that would match the signature:

void* operator new (Heap&, size_t);

In this case memory management is not left out. Instead you are
providing extra info to the allocation function that shall be used to
allocate the memory. The typical use case is the following:

Heap a;
Heap b;
Object* fromA = new(a) Object; // allocate from heap a
Object* fromB = new(b) Object; // allocate from heap b

As the new expression actually allocate memory through the passed heap
object, simply calling the destructor with a->~Object() will cause a
memory leak as the heap don't get the opportunity to release the memory.

Ganesh

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Francis Glassborow
Guest





PostPosted: Sat Sep 30, 2006 9:10 am    Post subject: Re: why isn't there a placement delete syntax Reply with quote

In article <451ce772$0$21345$db0fefd9 (AT) news (DOT) zen.co.uk>, Nick C
<nick (AT) google (DOT) com> writes
Quote:
There are some interesting comments here, but funamentally, the ability to
specify a placement delete syntax is an omission. Stroustrop is still
undecided whether this omission was the right choice.

How do you arrive at that conclusion?
The problem with having 'placement delete' is akin to that of
overloading the destructor. You would need to know which new was used in
order to call the correct delete. Of course we can actually do that by
using class scope overloads for operator new and operator delete but
allowing it otherwise is, IMO, recipe for chaos.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' and "You Can Program in C++"
see http://www.spellen.org/youcandoit
For project ideas and contributions:
http://www.spellen.org/youcandoit/projects


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Alberto Ganesh Barbati
Guest





PostPosted: Sat Sep 30, 2006 7:56 pm    Post subject: Re: why isn't there a placement delete syntax Reply with quote

Francis Glassborow ha scritto:
Quote:
In article <451ce772$0$21345$db0fefd9 (AT) news (DOT) zen.co.uk>, Nick C
nick (AT) google (DOT) com> writes
There are some interesting comments here, but funamentally, the ability
to
specify a placement delete syntax is an omission. Stroustrop is still
undecided whether this omission was the right choice.

How do you arrive at that conclusion?
The problem with having 'placement delete' is akin to that of
overloading the destructor. You would need to know which new was used in
order to call the correct delete. Of course we can actually do that by
using class scope overloads for operator new and operator delete but
allowing it otherwise is, IMO, recipe for chaos.


I totally agree with Francis. Moreover, my personal experience has shown
that relying on these error-prone techniques is seldom necessary. In
most scenarios where several custom memory allocation schemes need to
coexist, using higher-level constructs such as smart pointers is usually
a better choice. The first thing that comes to my mind is
tr1::shared_ptr and its custom deleter feature, which specifically
addresses the "how do I destroy this object" issue in a very nice and
safe way.

Ganesh

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.