2012-04-30 2 views
0

次のように、ツールの可読サイズのメモリプールを作成しています。可変サイズのメモリアロケータでC++でnewとdeleteを使用してクラッシュする

私はこのためのスタックトレースを持っていません。私はそれを見つけだして 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(); 
} 
+1

valgrindに興味のあることはありますか? – dasblinkenlight

+2

[テストケースかどうか](http://sscce.org)。 – Griwes

+0

valgrindを使って実行したり、デバッガでバックトレースを取得したり、コンパイラの警告レベルを 'delete void *'のようなものを捕まえるのに適切なレベルに設定したりといった通常の作業を試しましたか?それらのすべての結果はどうでしたか? – PlasmaHH

答えて

2

nextとnextChunkはどこにも指していないようです。また、MemoryChunkのデストラクタでは配列の削​​除が必要です。私がコードを間違って読んでいない限り、それは10の初心者です。

+0

申し訳ありませんが、私は "10のためのスターターがある"という意味を持っていませんでしたか?入力をありがとう。 – venkysmarty

+0

が明らかになりました。 – ColWhi

関連する問題