MemoryPool Failing from Efficient C++

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • wzcxjiao
    New Member
    • Jan 2011
    • 3

    MemoryPool Failing from Efficient C++

    'm currently fighting my way through an example of Single-Threaded Variable-Size Memory Manager in a chapter of the Efficient C++ book by Dov Bulka &David Mayhew. Unfortuantely, I'm starting to get code that won't compile and I am having a hard time finding an online errata or contacting the authors.

    For those familiar with the book, Chapter 6 covers rolling your own
    memory manager.

    My compile errors are with the lines saying
    "error C2143: syntax error : missing ';' before '<'"
    "error C4430: missing type specifier - int assumed. Note: C++ does not support default-int '.

    I'd love to be able to figure this out, but sadly, that's why I'm
    reading the book; I am not sure how this is failing.
    and in the end ,I want to write a memorypool which can support Multithreaded and Variable-Size Memory Manager Any help would be appreciated.

    - wzcxjiao

    Code:
    #ifndef __MEN113_H__
    #define __MEN113_H__
    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:
        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];
    }
    
    //MemoryChunk :: ~MemoryChunk() { delete [] mem; }// 
    
    
    void* MemoryChunk :: alloc (size_t requestSize)
    {
        void *addr = reinterpret_cast <void*>
    		//(reinterpret_cast<size_t>( mem) + bytesAlreadyAllocated);
           //(static_cast 
    	   ( _msize( 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;
    };
    #endif
    
    
    // the main file
    #include <windows.h>
    #include "iostream"
    #include"men113.h"
    //#include <vector>
    using namespace std;
    
    
    MemoryPool <Rational> *Rational::memPool = 0;// the failing
    
    int main()
    {
        //...
        Rational *array[1000];
    
        Rational::newMemPool();
    
        // Start timing here
    
        for (int j = 0; j < 500; j++)   {
             for (int i = 0; i < 1000; i++)   {
                  array[i] = new Rational(i);
                  }
             for (int i = 0; i < 1000; i++)   {
                  delete array[i];
                  }
             }
    
        // Stop timing here
    
        Rational::deleteMemPool();
    
       // ...
    	return 0;
    }
    Last edited by wzcxjiao; Jan 16 '11, 08:39 AM. Reason: have something wrong
  • horace1
    Recognized Expert Top Contributor
    • Nov 2006
    • 1510

    #2
    the class MemoryPool does not appear to be in men113.h

    Comment

    • wzcxjiao
      New Member
      • Jan 2011
      • 3

      #3
      I think it may be ByteMemoryPool, but in the book it was MemoryPool!alth ough there is no MemoryPool,ther e is something wrong esle!can you give me right one?thank you!

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        You just need to create memPool correctly:

        Code:
        //MemoryPool <Rational> *Rational::memPool = 0;// the failing 
        ByteMemoryPool* Rational::memPool = 0;

        Comment

        • wzcxjiao
          New Member
          • Jan 2011
          • 3

          #5
          I do it as you said,but when I debug,it says:

          Unhandled exception at 0x00411ad9 in mem113.exe: 0xC0000005: Access violation writing location 0x00001000.

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

            #6
            That is because when the code calls ByteMemoryPool: :expandStorage on construction of the ByteMemoryPool that method assumes that ByteMemoryPool: :listOfMemoryCh unks contains a valid value when it creates a new MemoryChunk.

            However ByteMemoryPool: :listOfMemoryCh unks is never initialised by any code so it presumably contains a random value which is unlikely to lead to good operation.

            Comment

            Working...