私は次のようにツールの可変サイズのメモリプールを書いています。
このためのスタックトレースはありません。ステップスルーすると、Rational :: deleteMemPool();でクラッシュしていることがわかりました。
なぜそうなのかわかりませんか?どんな入力でも大歓迎です。
ありがとう!
// MemoryChunkは、さまざまなサイズのメモリのチャンクをチャンクのシーケンスに文字列化するために使用されます。
class MemoryChunk {
public:
MemoryChunk (MemoryChunk *nextChunk, size_t chunkSize);
~MemoryChunk() {delete mem; }
inline void *alloc (size_t size);
inline void free (void* someElement);
// Pointer to next memory chunk on the list.
MemoryChunk *nextMemChunk() {return next;}
// How much space do we have left on this memory chunk?
size_t spaceAvailable() { return chunkSize - bytesAlreadyAllocated; }
// this is the default size of a single memory chunk.
enum { DEFAULT_CHUNK_SIZE = 4096 };
private:
// The MemoryChunk class is a cleaner version of NextOnFreeList. It separates the next pointer from
// the actual memory used for the allocated object. It uses explicit next and mem pointers, with no
// need for casting.
MemoryChunk *next;
void *mem;
// The size of a single memory chunk.
size_t chunkSize;
// This many bytes already allocated on the current memory chunk.
size_t bytesAlreadyAllocated;
};
MemoryChunk::MemoryChunk(MemoryChunk *nextChunk, size_t reqSize) {
chunkSize = (reqSize > DEFAULT_CHUNK_SIZE) ? reqSize : DEFAULT_CHUNK_SIZE;
next = nextChunk;
bytesAlreadyAllocated = 0;
mem = new char [chunkSize];
}
void* MemoryChunk :: alloc (size_t requestSize) {
void *addr = static_cast <void*> (static_cast <char*> (mem) + bytesAlreadyAllocated);
bytesAlreadyAllocated += requestSize;
return addr;
}
inline void MemoryChunk :: free (void *doomed) {}
class ByteMemoryPool {
public:
ByteMemoryPool (size_t initSize = MemoryChunk::DEFAULT_CHUNK_SIZE);
~ByteMemoryPool ();
// Allocate memory from private pool.
inline void *alloc (size_t size);
// Free memory previously allocated from the pool
inline void free (void* someElement);
private:
// A list of memory chunks. This is our private storage.
MemoryChunk *listOfMemoryChunks;
// Add one memory chunk to our private storage
void expandStorage(size_t reqSize);
};
// Construct the ByteMemoryPool object. Build the private storage.
ByteMemoryPool :: ByteMemoryPool (size_t initSize) {
expandStorage(initSize);
}
ByteMemoryPool :: ~ByteMemoryPool () {
MemoryChunk *memChunk = listOfMemoryChunks;
while (memChunk) {
listOfMemoryChunks = memChunk->nextMemChunk();
delete memChunk;
memChunk = listOfMemoryChunks;
}
}
void* ByteMemoryPool :: alloc (size_t requestSize) {
size_t space = listOfMemoryChunks->spaceAvailable();
if ( space < requestSize ) {
expandStorage(requestSize);
}
return listOfMemoryChunks->alloc(requestSize);
}
inline void ByteMemoryPool :: free (void *doomed) {
listOfMemoryChunks->free(doomed);
}
void ByteMemoryPool :: expandStorage(size_t reqSize) {
listOfMemoryChunks = new MemoryChunk(listOfMemoryChunks, reqSize);
}
class Rational {
public:
Rational (int a = 0, int b = 1 ) : n(a), d(b) {}
void *operator new(size_t size) {return memPool->alloc(size);}
void operator delete(void *doomed,size_t size) {memPool->free(doomed);}
static void newMemPool() { memPool = new ByteMemoryPool;}
static void deleteMemPool() { delete memPool; }
private:
int n; // Numerator
int d; // Denominator
static ByteMemoryPool *memPool;
};
ByteMemoryPool* Rational::memPool = 0;
int main(){
Rational *array[1000];
Rational::newMemPool();
// Start timing here
for (int j = 0; j < 1; j++) {
for (int i = 0; i < 5; i++) {
array[i] = new Rational(i);
}
for (int i = 0; i < 5; i++) {
delete array[i];
}
}
// Stop timing here
Rational::deleteMemPool();
}