tags:

views:

116

answers:

3

I am trying to implement a custom memory manager, I am wondering if there is a better way to implement this function as when i asked about void pointer arithmetic, several people thought that if i had a void* in C++, something was very wrong.

// allocates a page of memory.
void ObjectAllocator::allocatePage()
{    
    //if(OAStats_.PagesInUse_ >= Config_.MaxPages_)
        //throw exception

    void* buffer = ::operator new(OAStats_.PageSize_); // allocate memory, no constructor call.

    // =============== Setup the PageList_ ===============
    GenericObject* pNewNode = ::new(buffer) GenericObject();    // Construct GenericObject for the pagelist.
    pNewNode->Next = PageList_->Next;                            // pNewNode points to wherever PageList_ pointed to.
    PageList_->Next = pNewNode;                                    // PageList_ points to pNewNode
    pNewNode = NULL;                                            // dont need this handle anymore
    buffer = static_cast<char*>(buffer) + sizeof(GenericObject);    // move pointer to point after the generic object.

    // =============== Setup the FreeList_ ===============
    for(int i=0;i<Config_.ObjectsPerPage_;++i)
    {
        static GenericObject* pPreviousNode = NULL;            // static variable to hold the previous node
        pNewNode = ::new(buffer) GenericObject();            // Construct GenericObject for the freelist.
        pNewNode->Next = pPreviousNode;
        pPreviousNode = pNewNode;
        buffer = static_cast<char*>(buffer) + OAStats_.ObjectSize_;    // move pointer by ObjectSize.
        ++OAStats_.FreeObjects_;
    }
    FreeList_->Next = pNewNode;

    ++OAStats_.PagesInUse_;
    ++OAStats_.Allocations_;
}
+4  A: 

In C++, on raw bytes, use a char*, and don't think any less of yourself. It's The Right Thing To Do (tm). Especially if you wrap it in a higher level construct, like you have.

Merlyn Morgan-Graham
+4  A: 

If you need a block of memory for for storing a string (8-bit ANSI), it makes sense to declare a pointer to that buffer as char and operate on it.

In your case, you need a block of memory that is a 'blob', it has no inherent type, so you correctly chose void* to represent that blob.

Now you need to increment that pointer by the size of some object. You cannot perform arithmetic on a void pointer for obvious reasons, so what do you do? Cast it. There is no shame in that.

Tergiver
+2  A: 

There's nothing inherently wrong with the void*. However, what we often see is people coming from C who overuse void* when they should do something else. If you're managing raw memory blobs, then a void* is perfectly appropriate. However, there's rarely any other reason to do it.

DeadMG
+1. Out of interest, what are the typical ways in which to 'overuse void*' ?
JBRWilkinson
void* data, int size; memcpy(data, buffer, size); instead of using template and copy constructor.
DeadMG