Re: Efficient per-class allocator
On Oct 25, 6:22 am, Davin Pearson <davin.pear...@gmail.com> wrote:
Page 570 of Stroustrup's The C++ Programming Language (special
edition)
contains some code that serves my purpose. Page 472 of the second
edition also has some code. Combining the code from the two editions
yields a workable solution. Yes this is a good simple one, that will handle your use case. Except for one thing: This code has a bug: The reason it worked for your code is because you never initialized the int inside your class.
If you look at these two functions
void* Pool::alloc()
{
if (head == 0)
{
grow();
}
Link* p = head;
head = p->next;
return p;
}
void Pool::free(void* b)
{
Link* p = static_cast<Link*>(b);
p->next = head;
head = p;
}
and then consider that operator new/delete are really these four steps
combined:
//new X-->
void* mem=X::operator new(sizeof(X));
X*x=new (mem) X;//the way to explictly call the constructor
//use x, then delete x
x->~X();
X::operator delete(x);//free memory
you can easily see that the X stomps all over the Link structure. In
other words, Pool::alloc returns memory that was already initialized
as Pool::Link, and Pool::free assumes that you are pasing in an
initialized Link structure.
What you really want is something more like this
In the ctor:
Pool::Pool(unsigned int sz) : esize(sz+sizeof(Link)),head(0),chunks(0)
{}
void* Pool::alloc()
{
if (head == 0)
{
grow();
}
Link* p = head;
head = p->next;
return reinterpret_cast<char*>(p)+sizeof(Link*);
}
void Pool::free(void* b)
{
Link* p = static_cast<Link*>(reinterpret_cast<char*>(b)-
sizeof(Link*));
p->next = head;
head = p;
}
This still does not take alignment into consideration -- but this is
enough to work in a lot of cases.
But that number you reported is about as good as you are going to get
without actually making an allocator that never recycles used memory.
But something like that would be fun to try -- just keep advancing a
pointer on each call to alloc, and delete does nothing. This operates
just like your stack does. That boul dbe the becnhmark to compare
against-- not two empty function calls, which are hopefully just
optimized away
Lance
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]