Re: is this a dirty struct?
On May 28, 9:19 pm, "andrew_n...@yahoo.com" <andrew_n...@yahoo.com>
wrote:
Hi,
I'm wondering if the following trick is too dirty to be platform
safe? I'm mallocing
an area of memory bigger than my Pool class, and putting the array of
T's
just after the Pool. Also, I'm using reinterpret_cast instead of 2
static_casts.
I'm I doing the alignment properly?
No, you are aligning Pool but not T.
I just don't like the idea of 2
mallocs for
my pool when I could get by with one. The fragmentation.
Understandable. May I suggest different way?
Make your pool a union, allocate nodes+1, and make first
node keep the state. I would also use free list instead of keeping
index and count.
template <class T>
class Pool {
union {
struct {
int count;
int index;
};
align_type dummy;
};
public:
static Pool* NewPool (int count)
{
Pool* pool = static_cast<Pool*>(malloc(sizeof(Pool) +
count*sizeof(T)));
// dirty? i'm putting the array of objects just after the
aligned Pool object
You can't do it that way. You have to still align T properly.
.....
T* Next () const
{
// dirty?
// reinterpret_cast or 2 static_casts thru void*
return index == count ? 0 : reinterpret_cast<T*>(this+1) +
index++;
Besides alignment problem, you can't return just T*
as object is still not properly constructed.
This is what would I do:
template <class T,class align_t = size_t>
union Pool{
private:
Pool* next;
align_t a;
unsigned char t[sizeof(T)];
public:
// function new pool allocates chunks+1 as first Pool in a
// array will keep the state,
// then forms a linked list
static Pool* newPool(unsigned chunks)
{
chunks++;
assert(chunks);
Pool* c = new Pool[chunks];
c->next=0;
for (unsigned i=1;i<chunks;++i)
{
c[i].next=0;
c[i-1].next=c+i;
}
return c;
}
static void deletePool(const Pool* p)
{
delete[] p;
}
// function allocate returns first available chunk
// and sets next one
void* allocate()
{
void *p = next;
if(p)next=next->next;
return p;
}
// deallocate returns chunk to linked list
void deallocate(const void* p)
{
void *c = const_cast<void*>(p);
Pool* d = static_cast<Pool*>(c);
d->next = next;
next = d;
}
// you need these two, too, as allocate just returns uninitialized
// block, and also addresses returned by expression new and alloc
// may differ
static T* construct(void* p)
{
return new(p) T();
}
static void destruct(const T* p)
{
p->~T();
}
};
Greetings, Branimir.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]