Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Memory Manager

Tags:

c++

I am trying to implement a custom memory manager and I am wondering if there is a better way to implement this function, as when I am 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_;
}
like image 767
aCuria Avatar asked Jul 31 '10 12:07

aCuria


3 Answers

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.

like image 200
Tergiver Avatar answered Nov 15 '22 12:11

Tergiver


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.

like image 7
Merlyn Morgan-Graham Avatar answered Nov 15 '22 13:11

Merlyn Morgan-Graham


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.

like image 2
Puppy Avatar answered Nov 15 '22 14:11

Puppy