 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Matthias Hofmann Guest
|
Posted: Fri Oct 24, 2003 7:34 pm Post subject: How do I match placement new? (5.3.4/19) |
|
|
Hello!
Section 5.3.4/19 tell me that
"A declaration of a placement deallocation function matches the declaration
of a placement allocation function if it has the same number of parameters
and, after parameter transformation (8.3.5), all parameter types except the
first are identical."
In the standrad library there is a placement form of operator new that looks
like
void* operator new( size_t size, void* p );
which is typically called like
void f()
{
void p* = GetMemoryFromSomewhere( sizeof ( T ) );
T* p = new( p ) T;
...
p->~T();
FreeMemory( p );
}
How do I declare an operator delete that matches this form of operator new?
In order to meet the requirements of the standard, it would have to be
void operator delete( void* p1, void* p2 );
but this seems ridiculous to me...
My concern is that the call to new in the call above might throw an
exception. I could rewrite the function like this, of course:
void f()
{
void p* = GetMemoryFromSomewhere( sizeof ( T ) );
try
{
T* p = new( p ) T;
}
catch( .. )
{
FreeMemory( p );
}
...
p->~T();
FreeMemory( p );
}
Is this a good solution?
Best regards,
Matthias Hofmann
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ivan Vecerina Guest
|
Posted: Sun Oct 26, 2003 5:05 am Post subject: Re: How do I match placement new? (5.3.4/19) |
|
|
Hi Matthias,
| Quote: | Section 5.3.4/19 tell me that
"A declaration of a placement deallocation function matches the
declaration
of a placement allocation function if it has the same number of parameters
and, after parameter transformation (8.3.5), all parameter types except
the
first are identical."
In the standrad library there is a placement form of operator new that
looks
like
void* operator new( size_t size, void* p );
.....
How do I declare an operator delete that matches this form of operator
new?
In order to meet the requirements of the standard, it would have to be
void operator delete( void* p1, void* p2 );
but this seems ridiculous to me...
|
This placement-delete function is indeed defined in the standard
library (see 18.4.1.3).
Each placement-new shall have a corresponding placement-delete
function defined. The purpose of the latter is to release the memory
allocated by the placement-new in case the construction of the
object allocated in a new-expression throws an exception.
This memory could not otherwise be released by the calling code.
This is the only purpose of the placement delete, which cannot
otherwise be called explicitly from a delete-expression.
Note that in the case of the 'real' placement new above, the
delete(void*, void*) implementation intentionally performs no action,
because it cannot know where the memory comes from. So the caller
is responsible to eventually release the memory, if needed.
This is exactly what you did in the code below:
| Quote: | My concern is that the call to new in the call above might throw an
exception. I could rewrite the function like this, of course:
void f()
{
void p* = GetMemoryFromSomewhere( sizeof ( T ) );
try
{
T* p = new( p ) T;
}
catch( .. )
{
FreeMemory( p );
}
...
p->~T();
FreeMemory( p );
}
Is this a good solution?
Yes, it is an ok solution, although in this example |
you will want to either:
- re-throw the error in your catch(...) block,
- or put the p->~T() call within the try block,
and have a single call to FreeMemory in the end.
An alternative would be to define your own placement-new
overload, and its matching placement-delete operator:
void* operator new(std::size_t size, Storage& sto)
{ ... return the memory allocated from 'sto' ... }
void operator delete(void* ptr, Storage& sto)
{ ... release the memory at 'ptr' back to 'sto' ... }
The benefit of this is that the placement-delete is
automatically called should T's constructor fail,
and the exception is automatically re-thrown.
If you do this, you should also watch for the fact that
yet another pair of new-delete functions is needed
if you want to support the allocation of arrays:
void* operator new[](std::size_t size, Storage& sto);
void operator delete[](void* ptr, Storage& sto)
Regards,
Ivan
--
http://ivan.vecerina.com
http://www.brainbench.com <> Brainbench MVP for C++
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
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
|
|