 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Guest
|
Posted: Sun Feb 26, 2006 12:06 pm Post subject: Why the inconsistent form of operator new/delete overloading |
|
|
As we all know, operator new()/new[]() can be overloaded and then
called in new-expression.
E.g. Suppose we have some sort of Fast Memory Pool, we could sketch
something like this:
void* operator new(size_t, FastMemory&);
void operator delete(void*,FastMemory&);
the usage of the overloaded new above would of course be:
px = new (fast_mem) X;
but then I got stucked on trying to use the seamingly absolutely
natural way to delete px, that is:
delete (fast_mem) px; // Here! Error Occurs!
So why is this? And what's the alternative?
Of course, I really wanna know the rationale behind this language rule,
I would really appreciate your help, thanks in advance;)
--
Regards!
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Guest
|
Posted: Sun Feb 26, 2006 5:06 pm Post subject: Re: Why the inconsistent form of operator new/delete overloa |
|
|
Yes, that's true - you cannot pass additional arguments to operator
delete. You should lookup you pool by object's address or save required
information, e.g:
void operator new(size_t s, FastMemory& m)
{
static const size_t ptr_size=sizeof(void*);
void* p=m.allocate(s+ptr_size);
reinterpret_cast<void*&>(p)=&m;
return p+ptr_size;
}
void operator delete(void* p,size_t s)
{
static const size_t ptr_size=sizeof(void*);
FastMemory* m=reinterpret_cast<FastMemory*>(p);
m.deallocate(p-ptr_size,s+ptr_size);
}
So, each object allocated by FastMemory pool has that particular pool
stated just before object's memory region starts.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Thomas Richter Guest
|
Posted: Sun Feb 26, 2006 5:06 pm Post subject: Re: Why the inconsistent form of operator new/delete overloa |
|
|
pongba (AT) gmail (DOT) com wrote:
| Quote: | As we all know, operator new()/new[]() can be overloaded and then
called in new-expression.
E.g. Suppose we have some sort of Fast Memory Pool, we could sketch
something like this:
void* operator new(size_t, FastMemory&);
void operator delete(void*,FastMemory&);
the usage of the overloaded new above would of course be:
px = new (fast_mem) X;
but then I got stucked on trying to use the seamingly absolutely
natural way to delete px, that is:
delete (fast_mem) px; // Here! Error Occurs!
|
Which is invalid. The corresponding delete operation is
delete px;
and it the job of your operator delete() to find and fetch the memory
pool the class has been allocated from. That is, you *must* overload
operator delete(void *) plus its array form. The other operator delete
is the "placement form" and it is only used if the constructor of an
object calls the placement new operator and then fails to construct the
object up to the end, in which case the corresponding operator delete
will delete the left-over memory.
operator new(size_t, mem)
was originally intended to "place" objects into already allocated memory
where this memory is passed as the second argument. Clearly, this memory
would normally not require deletion - you would call the destructor,
then throw the memory away in the same way you allocated it - outside
the scope of the operator new/delete mechanism.
| Quote: | And what's the alternative?
|
Overload the placement new, and the regular delete operator. Within
operator new(x,y), allocate enough memory for the object and a pointer
to the memory pool, keep care of alignment. Within operator delete(),
fetch the pointer to the memory pool from the raw memory you got as
argument, then call the release function of the pool.
So long,
Thomas
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Ron Natalie Guest
|
Posted: Sun Feb 26, 2006 9:06 pm Post subject: Re: Why the inconsistent form of operator new/delete overloa |
|
|
pongba (AT) gmail (DOT) com wrote:
| Quote: | but then I got stucked on trying to use the seamingly absolutely
natural way to delete px, that is:
delete (fast_mem) px; // Here! Error Occurs!
There's no such thing as a placement delete expression. |
The only time the non-default deallocation function is
called is when an exception happens during object creation.
Your choices are either:
1. Make your default deallocation function smart enough
to notice stuff allocated with the placement new and do the
right thing.
2. Explicitly call the destuctor and do what ever you need
to delete "fast_mem" (possibly in a function):
template <class T> void DeleteFastMem(T* t) {
t->~T();
// reclaim t here.
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Jeffrey Schwab Guest
|
Posted: Sun Feb 26, 2006 9:06 pm Post subject: Re: Why the inconsistent form of operator new/delete overloa |
|
|
kerzum (AT) mail (DOT) ru wrote:
| Quote: | void operator new(size_t s, FastMemory& m)
|
The return type should be a pointer type, not void.
| Quote: | {
static const size_t ptr_size=sizeof(void*);
void* p=m.allocate(s+ptr_size);
reinterpret_cast<void*&>(p)=&m;
|
What is the purpose of this cast?
| Quote: | return p+ptr_size;
|
Adding a size_t to a void* should be a compile-time error, since void
does not have any size. This might work better:
return static_cast<char*>(p)+ptr_size;
| Quote: | }
void operator delete(void* p,size_t s)
{
static const size_t ptr_size=sizeof(void*);
FastMemory* m=reinterpret_cast<FastMemory*>(p);
m.deallocate(p-ptr_size,s+ptr_size);
|
The FastMemory* m is a pointer, so instead of m., you'll have to use m->
here. Also, p-ptr_size should not work for the same reason p+ptr_size
does not work. You could ram something like this through the compiler:
m->deallocate(static_cast<char*>(p)-ptr_size,s+ptr_size);
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Kodt Guest
|
Posted: Mon Feb 27, 2006 11:06 am Post subject: Re: Why the inconsistent form of operator new/delete overloa |
|
|
pongba (AT) gmail (DOT) com wrote:
| Quote: | As we all know, operator new()/new[]() can be overloaded and then
called in new-expression.
E.g. Suppose we have some sort of Fast Memory Pool, we could sketch
something like this:
void* operator new(size_t, FastMemory&);
void operator delete(void*,FastMemory&);
the usage of the overloaded new above would of course be:
px = new (fast_mem) X;
but then I got stucked on trying to use the seamingly absolutely
natural way to delete px, that is:
delete (fast_mem) px; // Here! Error Occurs!
So why is this? And what's the alternative?
Of course, I really wanna know the rationale behind this language rule,
I would really appreciate your help, thanks in advance;)
|
The alternative is to call destructor and operator delete separately:
template<class T> void delete_fastmem(FastMemory& fast_mem, T* ptr)
{
if(!ptr) return;
ptr->~T();
operator delete(ptr, fast_mem);
}
Another alternative is to assert that there is only one fast_mem in the
system, and overload operator new and delete for given class
class Some
{
public:
static void* operator new(size_t n) { return alloc_at_fastmem(n); }
static void operator delete(void* p) { free_at_fastmem(p); }
........
};
that makes common forms of new/delete expressions to use your
allocator.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Mon Feb 27, 2006 12:06 pm Post subject: Re: Why the inconsistent form of operator new/delete overloa |
|
|
Jeffrey Schwab wrote:
| Quote: | kerzum (AT) mail (DOT) ru wrote:
|
[...]
| Quote: | return p+ptr_size;
Adding a size_t to a void* should be a compile-time error, since void
does not have any size. This might work better:
return static_cast<char*>(p)+ptr_size;
|
This still leaves open the possibility (probability, on a 32 bit
machine) that the resulting pointer is not sufficiently aligned.
--
James Kanze GABI Software
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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Guest
|
Posted: Mon Feb 27, 2006 3:06 pm Post subject: Re: Why the inconsistent form of operator new/delete overloa |
|
|
kerzum (AT) mail (DOT) ru wrote:
| Quote: | void operator delete(void* p,size_t s)
{
static const size_t ptr_size=sizeof(void*);
FastMemory* m=reinterpret_cast<FastMemory*>(p);
m.deallocate(p-ptr_size,s+ptr_size);
}
|
I do not think this is the right way. How do you presume that all the
chunks passed to operator delete has the same book-keeping structure?
That is, if we now pass some regular allocated memory chunk to operator
delete, like this:
int* p = new int;
delete p; // of course p doesn't point somewhere in FastMemory area,
but the overloaded operator delete() above treats it as one, and try to
"reinterpret_cast<FastMemory*>(p-ptr_size)", how could this succeed as
long as p doesn't point somewhere in FastMemory pool?
In a word, I don't think this alternative is "the" alternative. And I
strongly hope to know why the language forbids the seemingly natural
way to do this(that is, delete (fastMem) p ? Is there something we
don't know?
P.S. The second alternative is imperfect, too. It's highly
inconsistent.Don't you think?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
RenjithMohan Guest
|
Posted: Mon Feb 27, 2006 5:06 pm Post subject: Re: Why the inconsistent form of operator new/delete overloa |
|
|
pon...@gmail.com wrote:
| Quote: | but then I got stucked on trying to use the seamingly absolutely
natural way to delete px, that is:
delete (fast_mem) px; // Here! Error Occurs!
|
Here the error occurs since there is no such thing as a placement
delete operator.
So in order to achieve this you will have to call the form of your
delete operator.But before that you are supposed to call the dtor of
the class
like this
px->~X; //call the dtor
X::operator delete(px, fast_mem);
This will really call your overloaded delete operator.
The code inside your delete operator is really implementation dependent
.. It depends on how you want the pool to behave. Most probably you
would be just marking one of your allocated nodes as allocable rather
than giving it back to the memory manager of the OS.
[ 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
|
|