Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

Memory Manager for C++

1.32/5 (17 votes)
28 Jul 2006CPOL2 min read 1  
Memory manager for C++ that automatically deletes any heap objects not in use.

Introduction

Well, I came up with a cool project to try out. This turned out to be a memory manager for C++. Its purpose is to automatically delete heap objects that your application no longer uses. No need to manually delete them. But better yet - it deletes them instantly they are no longer needed. You don't need to wait a specified amount of time for it to delete the objects, nor will it take much processor time to track down all the objects and delete them. This is a simple, yet very functional class. Righty-o, here's the code for the class:

C++
#pragma once
#pragma warning ( disable: 4312 )

template<typename T> class CMemoryManager
{
private:
    template<typename T> class Pointer
    {
        friend class CMemoryManager;
        T* p;
        DWORD* pdwRefCount;
    public:
        template<typename Type> void operator = (Type value)
        { 
            *p = value;
        }
        template<typename Type> bool operator == (Type value)
        {
            return (*p == value);
        }
        operator T* () { return p; }
    };
    Pointer<T> p;
public:
    CMemoryManager()
    {
        Init();
    }
    CMemoryManager(T* pNew)
    {
        Init();
        SetNewPointer(pNew);
    }
    CMemoryManager(int val)
    {
        Init();
        SetNewPointer((T*)val);
    }
    CMemoryManager(const CMemoryManager& rmm)
    {
        Init();
        UpdateMemoryManager(rmm);
    }
    ~CMemoryManager() 
    { 
        if (p.pdwRefCount == NULL) return;
        if (*p.pdwRefCount == 0 || --(*p.pdwRefCount) == 0) 
        {
            delete p.p;
            delete p.pdwRefCount;
            Init();
        }
    }
    void Init()
    {
        p.pdwRefCount = NULL;
        p.p = NULL;
    }
    void AssignNewPointer(const T* pNew)
    {
        p.p = (T*)pNew;
    }
    void CheckRefCount()
    {
        if (p.pdwRefCount == NULL) NewRefCounter();
    }
    void SetRefCount(DWORD dwNewCount)
    {
        CheckRefCount();
        *p.pdwRefCount = dwNewCount;
    }
    void IncreaseRefCount()
    {
        CheckRefCount();
        (*p.pdwRefCount)++;
    }
    void NewRefCounter()
    {
        p.pdwRefCount = new DWORD;
        *p.pdwRefCount = 0;
    }
    void SetNewPointer(const T* pNew)
    {
        Delete();
        AssignNewPointer(pNew);
        IncreaseRefCount();
    }
    void Delete()
    {
        this->~CMemoryManager();
        Init();
    }
    void UpdateMemoryManager(const CMemoryManager& rmm)
    {
        Delete();
        AssignNewPointer(rmm.p.p);
        p.pdwRefCount = rmm.p.pdwRefCount;
        IncreaseRefCount();
    }
    void operator = (int val)
    {
        SetNewPointer((T*)val);
    }
    void operator = (const T* pmm)
    {
        SetNewPointer(pmm);
    }
    void operator = (const CMemoryManager* pmm)
    {
        UpdateMemoryManager(*prmm);
    }
    void operator = (const CMemoryManager& rmm)
    {
        UpdateMemoryManager((CMemoryManager&)rmm);
    }
    void SetNewAddr(T* pNewAddr, DWORD dwRefCount)
    {
        Delete();
        SetNewPointer(pNewAddr);
        SetRefCount(dwRefCount);
    }
    void Detach()
    {
        if (*p.pdwRefCount == 1) 
        {
            delete p.pdwRefCount;
            delete p.p;
        }
        p.pdwRefCount = NULL;
        p.p = NULL;
    }
    int GetSize() { return sizeof(*p.p); }
    Pointer<T>& operator * () { return p; }
    T* operator -> () { return p.p; }
    operator T* () { return p.p; }
    operator void* () { return p.p; }
    void operator delete(void* p) { }
    // Do nothing if attempting to delete the object.
    // Object will automatically be deleted by the class.

    T* GetPointer() { return p.p; }
    bool operator == (int nCompare) { return (p.p == (T*)nCompare); }
    operator bool () { return (p.p != NULL); }
};

#pragma warning ( default: 4312 )
#define pp CMemoryManager

What you simply do, is encapsulate all your heap memory in the CMemoryManager class. You can then use those pointers as if they were not encapsulated. Or, you are supposed to at least. Try it out! See how it works, and report if anything doesn't work. I don't know if intellisense in Visual Studio 2003 or less will actually detect the class members for the actual pointers, but in 2005, it works perfectly. So, again, try it out, let me know what you think and how it works. No more pesky pointers that you need to delete manually! On a side note, do not use "delete" on them. Instead, if you want to release the pointer, call the member method Delete. If the object is no longer in use (reference count is 0), then it is freed. Also remember to always use the container. If you assign a normal pointer to the memory manager, it will not keep the reference count! So, always assign the actual memory manager object, if possible. And lastly, do not use this class to encapsulate memory pointers which are not your responsibility to release. Only use them on memory your own. And, I would recommend that you only use it on newly allocated objects that you allocate yourself.

I've updated the class. It is much more efficient and better now. No bugs as far as I can see.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)