473,406 Members | 2,369 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

how to write a stateful allocator with gcc and stl

Hi,

I have a simple "memPool' class that simply maintains a linked list of
chunks from which allocation requests are made. The whole thing is
deleted all at once upon destruction. So far, so good.

Then I tried to make an allocator for this and use it with std::list
with no success. I modeled my allocator code from gcc's
new_allocator.h. I modified the allocate() and deallocate() functions
and copy constructors, and added a "memPool" member and a
corresponding constructor to initialize it.

Using gdb, I see that when the list is constructed, it uses the
allocator's default constructor instead of using the allocator's copy
constructor, and thus, the allocator state is lost. Of course this
segfaults during the first attempt to use the (garbage) psMemPool
pointer.

Is it even possible to achieve what I want? It feels like I am close
but I don't really know where to go from here.

Please find my sample code below.

Thanks in advance,
Mike

-----------------------------------------------------------------------------------------------------------------------
////////////////////////////// memory pool
#include <cstdlib>

class tMemPool
{
private:
struct tNode
{
char *pcMemory;
tNode *psNext;
};
unsigned int uiOffset, uiSize, uiAlign;
tNode *psHead, *psCurr;
tNode * addNode(void);
protected:
void * alloc(size_t _ui) {return malloc(_ui);}
void dealloc(void *_pv) {free(_pv);}
public:
tMemPool(unsigned int _uiSize, unsigned int _uiLog2Align = 3);
~tMemPool();
void * allocate(size_t _ui);
};

tMemPool::tMemPool(unsigned int _uiSize, unsigned int _uiLog2Align) :
uiOffset(0), uiSize(_uiSize)
{
uiAlign = (1 << _uiLog2Align) - 1;
psHead = psCurr = addNode();
}

tMemPool::~tMemPool()
{
while (psHead)
{
tNode *psCurr = psHead->psNext;
dealloc(psHead);
psHead = psCurr;
}
}

tMemPool::tNode * tMemPool::addNode(void)
{
tNode *ps = reinterpret_cast<tNode *>(alloc(sizeof(tNode) +
uiSize));
ps->pcMemory = reinterpret_cast<char *>(ps + 1);
ps->psNext = NULL;
return ps;
}

void * tMemPool::allocate(size_t _ui)
{
void *pv;

if (_ui (uiSize - uiOffset))
{
if (uiSize < _ui)
uiSize = _ui;
psCurr->psNext = addNode();
psCurr = psCurr->psNext;
uiOffset = 0;
}

pv = reinterpret_cast<void *>(psCurr->pcMemory + uiOffset);
uiOffset += (_ui + uiAlign) & ~uiAlign;
return pv;
}

////////////////////////////// memory pool allocator

#include <cstddef>

template<typename T>
class tMemPoolAllocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T * pointer;
typedef const T * const_pointer;
typedef T& reference;
typedef const T & const_reference;
typedef T value_type;

template<typename Ustruct rebind {typedef tMemPoolAllocator<U>
other;};
tMemPoolAllocator(void) throw() : psMemPool(0) {}
tMemPoolAllocator(tMemPool *_ps) throw() : psMemPool(_ps) {}
tMemPoolAllocator(const tMemPoolAllocator &_s) throw() :
psMemPool(_s.psMemPool) {}
template<typename UtMemPoolAllocator(const tMemPoolAllocator<U>
&_s) throw() : psMemPool(_s.psMemPool) {}
~tMemPoolAllocator() throw() {}
pointer address(reference _x) const {return &_x;}
const_pointer address(const_reference _x) const {return &_x;}
pointer allocate(size_type _n, const void* = 0) {return
static_cast<T*>(psMemPool->allocate(_n * sizeof(T)));}
void deallocate(pointer _p, size_type) {}
size_type max_size() const throw() {return size_t(-1) / sizeof(T);}
void construct(pointer _p, const T& _val) {::new(_p) T(_val);}
void destroy(pointer _p) {_p->~T();}
// state
tMemPool *psMemPool;
};

template<typename T>
inline bool operator==(const tMemPoolAllocator<T&_s0, const
tMemPoolAllocator<T&_s1) {return _s0.psMemPool == _s1.psMemPool;}

template<typename T>
inline bool operator!=(const tMemPoolAllocator<T&_s0, const
tMemPoolAllocator<T&_s1) {return _s0.psMemPool != _s1.psMemPool;}

////////////////////////////// simple test

#include <list>
int main(void)
{
tMemPool sPool(1024, 2);
tMemPoolAllocator<intsPoolAllocator(&sPool);

std::list<int, tMemPoolAllocator<int l;
l.push_back(0);

return 0;
}
Jan 12 '08 #1
3 4625
I forgot to mention that I am using
gcc version 4.2.3 20071123 (prerelease) (Debian 4.2.2-4)
Jan 12 '08 #2
On Jan 12, 10:25*am, Mike <hammero...@yahoo.comwrote:
Hi,
Using gdb, I see that when the list is constructed, it uses the
allocator's default constructor instead of using the allocator's copy
constructor, and thus, the allocator state is lost. *Of course this
segfaults during the first attempt to use the (garbage) psMemPool
pointer.

Is it even possible to achieve what I want? *It feels like I am close
but I don't really know where to go from here.
Yes it is possible.
One rule of thumb when using stateufl STL allocators is NOT to allow
default construction. Then your sample would not compile, showing
where the error is:

tMemPool sPool(1024, 2);
tMemPoolAllocator<intsPoolAllocator(&sPool);
std::list<int, tMemPoolAllocator<int l; //BOOOM!!!!!
//this line should read
std::list<int, tMemPoolAllocator<int l(sPoolAllocator);
l.push_back(0); //should be OK

For more info, read http://www.lancediduck.com/papers/Cpp/StatefulSTL.pdf
and http://www.open-std.org/jtc1/sc22/wg...2007/n2486.pdf
Lance


Jan 12 '08 #3
Yep - I should have noticed that stl::list's default constructor took
an allocator for its (optional) argument:

explicit
list(const allocator_type& __a = allocator_type())
: _Base(__a) { }

I've never had a reason to construct a list with a specific allocator
instance before.
Everything works perfectly now.

Thanks,
Mike
Jan 13 '08 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Ralf Schneeweiß | last post by:
Hi, there is a book from Andre Wilms describing how to write allocators for STL containers. Unfortunately the MS VC++ Compiler is not supporting the full ANSI standard in the template part of the...
5
by: Scott Brady Drummonds | last post by:
Hi, everyone, A coworker and I have been pondering a memory allocation problem that we're having with a very large process. Our joint research has led us to the conclusion that we may have to...
3
by: Bernhard Kick | last post by:
Hi all, I saw this code in the book "Accelerated C++" (chapt 11, iirc): template <class T> class Vec { ... std::allocator<T> alloc; // object to handle memory allocation // ??would static...
7
by: Grahamo | last post by:
Hi, can anybody tell me where I can get the boiler plate code for std::allocator. I need to have my version of new and delete called and want to get reference code. My compilers headers are all...
11
by: Chris Dams | last post by:
Dear all, I found out that the program #include<vector> using namespace std; int main() { vector<int*> v(2,0);
11
by: nosipho | last post by:
Hi guys, I've got this PC on my network. I can access everything on it on the network but I can't ping it. I tried pinging with the computer name and the IP adress aswell but It just doesn't want...
6
by: Paavo Helde | last post by:
Juha Nieminen <nospam@thanks.invalidwrote in news:47f91b3c$0$8161 $4f793bc4@news.tdc.fi: I would guess that most speedup comes from the fact that the general allocator is thread-safe and yours...
6
by: Juha Nieminen | last post by:
I tested the speed of a simple program like this: //------------------------------------------------------------ #include <list> #include <boost/pool/pool_alloc.hpp> int main() { typedef...
3
by: maneshborase | last post by:
Hi friends, I am facing one serious problem in my application. I am trying to open dicom image file (.dcm) has size around 400 MB. But I am getting and unhandy exceptions, Some time, ...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.