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 the inconsistent form of operator new/delete overloading

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






PostPosted: Sun Feb 26, 2006 12:06 pm    Post subject: Why the inconsistent form of operator new/delete overloading Reply with 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;)

--
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






PostPosted: Sun Feb 26, 2006 5:06 pm    Post subject: Re: Why the inconsistent form of operator new/delete overloa Reply with quote



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





PostPosted: Sun Feb 26, 2006 5:06 pm    Post subject: Re: Why the inconsistent form of operator new/delete overloa Reply with quote



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.

Quote:
So why is this?

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





PostPosted: Sun Feb 26, 2006 9:06 pm    Post subject: Re: Why the inconsistent form of operator new/delete overloa Reply with quote

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





PostPosted: Sun Feb 26, 2006 9:06 pm    Post subject: Re: Why the inconsistent form of operator new/delete overloa Reply with quote

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);


Quote:
}

[ 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





PostPosted: Mon Feb 27, 2006 11:06 am    Post subject: Re: Why the inconsistent form of operator new/delete overloa Reply with quote

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





PostPosted: Mon Feb 27, 2006 12:06 pm    Post subject: Re: Why the inconsistent form of operator new/delete overloa Reply with quote

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






PostPosted: Mon Feb 27, 2006 3:06 pm    Post subject: Re: Why the inconsistent form of operator new/delete overloa Reply with quote

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) pWink? 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





PostPosted: Mon Feb 27, 2006 5:06 pm    Post subject: Re: Why the inconsistent form of operator new/delete overloa Reply with quote

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
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.