Re: memory pool allocator
Alan Wright wrote:
Hi,
I have a problem and I'm hoping someone might be able to point me in the
right direction.
At the moment, I have a list control written in MFC, that internally stores
all data required
for the control (cell values). I effectively store an array of structures;
the structure defines
data to be displayed per list row. I need to store a *lot* of data in the
structure, including
large unicode strings and also I'm currently loading around ~20,000 rows
into the control.
I discovered (through profiling) early on, that memory allocation when
loading the list was
a major issue, and solved this by creating a memory pool that would store
all structures
and strings. This pool (allocated in 256k chunks), is then wiped-out
completely when
the list is re-loaded - therefore there is no requirement for deallocation
(or freeing)
individual elements.
My problem is that I would like to move this from MFC to an STL model.
1) I would like to replace my array of structures with a vector.
2) I would like to define my own std::allocator class that would handle
memory pooling.
3) I would like the structures I use (that contain std::wstrings) to use my
memory pool allocator.
4) I would like the std::wstrings contained in these structures to use my
memory pool allocator.
Now, I can do this quite easily - there are plenty of examples out there of
how to implement
a memory pool allocator, but my problem is:
How can I make all memory allocations required by my control to internal to
the control itself.
By initializing your containers and strings with a specific pool allocator.
For example, I might have multiple instances of my list control, however I
*don't* want them
to share the same memory pool, this is because the pool is completely
wiped-out when the list is
re-loaded or destroyed (this technique gives me very good performance).
Also, by using my own memory pool allocator (with a disabled deallocate
method), will I
run into problems when it's used for std::wstrings?
It sounds like your current pool allocator is global. All you need to do
is to give it some state. Then the list control constructor will create
one of these allocators, and pass it around to all the vectors and
wstrings. e.g.
template <class T>
class pool_alloc
{
//exposition only
shared_ptr<pool> m_pool;
public:
//no default constructor
pool_alloc(shared_ptr<pool> pool)
:m_pool(pool){}
//allocator interface
};
Then in your list control:
ListControl::ListControl()
:m_alloc(new pool(initial_size))
{ //etc.
}
Then, when you create any containers or strings, you initialize them
with the specific pool allocator they are supposed to be using.
std::vector<Row, pool_alloc<Row> > rows(m_alloc);
Tom