Hey!
I need some help with a strange behaviour on different types.
I have a class ("clsMem" - see below) used to organize data in memory, which shoud be faster then normal memory-management.
The class has a delimiter-value (min). If a amount of memory smaller then min is requested, allocatoion works linear (N bytes requested -> N bytes reserved), otherwise (if requested memory exeeds min), a block of the size 2^X will be reseved, where X is minimal possible value to sotre the requested data (like ie. requested: 102 byte, reserved: 128 byte, X = 7).
Allocating memory does not return a pointer, but an id (some kind of handle) which can be used to access data independent of the current physical position.
Memory is not really freed!
Every rereved block has group-id (grp) which corrosonds with the mentioned X like this (if min has a value of ie. 16): Requested: 6 byte -> group-id = 6; Requested: 10 byte -> group-id = 10; Requested: 16-31 byte -> group-id = 17; Requested: 32-63 byte -> group-id = 18 etc. Like this, the number of groups is limited. If min has a value of 128, 128+5 group-id's are needed, for data-blocks of 128^5 bytes.
For each group, a dynamic array (clsDynArray<int> emptyS[_MEM_MAX]) is created. If some data is not neended anymore, it's id is sored in the corresponding array for later use. If a amont of memory with the same group is requested, the block will be recyceld without further allocations.
The problem is the "clsDynArray<char> grp;" implementation. If min is > 127, some more then 127 grops are needed. For this, the char-type in "clsDynArray<char> grp" is not enough. Therefore "grp" shoud be declared as something like "clsDynArray<int>" or "clsDynArray<short>". But both doesn't work.
Whatever type i try except of type char, keeps cought in an endless loop and i have no idea why. Maybe someone else finds out...
Thank you for reading!
Best,
Frank
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
const int _SHORT_MEM = 1;//128;
const int _MAX_MEM = _SHORT_MEM+64;
class clsMem {
public:
virtual ~clsMem() {};
clsMem() : min(_SHORT_MEM) { };
inline void free (const int &id) { if (id == 0) return; int idx = grp[id]; emptyS[idx].Push(id); };
inline int alloc (int bytes = 1) {
register int id(pos.uLen); register int newGrp(0); register int size(1);
if (bytes > min) {
newGrp = bytes <= min ? bytes : log2(bytes)+1;
size = bytes <= min ? bytes : min<<(newGrp-min+1);
}
else { newGrp = bytes; size = bytes; }
if (emptyS[newGrp].uLen <= 0) { register char *tp(&*data); pos.Push(data.resizeBy(size));
if (tp != &*data) grp.Push(newGrp);
}
else id = *emptyS[newGrp].Pop(); return id;
};
};
inline int BlockSize (const int &id) { return grp[id] <= min ? grp[id] : min<<(grp[id]-min+1);}
const int min;
clsDynArray<int> emptyS[_MAX_MEM];
clsDynArray<unsigned int> pos;
clsDynArray<char> grp;
clsDynArray<char> data;
};
|
DynArray declaration:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
template <class T> struct clsDynArray {
public:
virtual ~clsDynArray();
clsDynArray(unsigned int min = 100, unsigned char fakt = 2);
inline void Clear () {wxMessageBox("clsDynArray->Clear() fehlt noch");}
inline unsigned int resizeBy (const int &count);
inline T *Pop (const int count = 1);
inline unsigned int Push (const T &data);
inline T &operator[] (const register unsigned int &idx);
inline T *operator() (const register unsigned int idx);
inline T &operator* () { return *ptr; };
unsigned int max;
unsigned int uLen;
T *ptr;
const unsigned char fkt;
};
|
DynArray implementation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
template <class T> clsDynArray<T> ::~clsDynArray() { delete[] ptr; }
template <class T> clsDynArray<T> :: clsDynArray(unsigned int min, unsigned char fakt) : max(min), fkt(fakt), uLen(0), ptr((T*)malloc(min * sizeof(T))) {}
template <class T> unsigned int clsDynArray<T> :: resizeBy(const int &count) { register unsigned int tmp(max), nc(uLen + count);
while (nc > tmp) tmp *= fkt; if (tmp != max) ptr = (T*)::realloc(ptr, tmp * sizeof(T)); max = tmp;
tmp = uLen; uLen = nc; new (&ptr[tmp]) T [uLen-tmp];
return tmp ;
}
template <class T> T &clsDynArray<T> :: operator[](const unsigned int &idx) { if(idx >= uLen) resizeBy(1 - uLen + idx); return ptr[idx]; }
template <class T> T *clsDynArray<T> :: operator()(const unsigned int idx) { if(idx >= uLen) resizeBy(1 - uLen + idx); return &ptr[idx]; }
template <class T> unsigned int clsDynArray<T> :: Push(const T &data){ unsigned int tmp(uLen); ::memcpy(operator()(uLen), &data, sizeof(T)); return tmp; }
template <class T> T *clsDynArray<T> :: Pop (int count){ return (uLen >= count) ? &ptr[(uLen-=count)] : (uLen > 0) ? &ptr[(uLen-=uLen)] : ptr; }
|