Click here to Skip to main content
15,867,308 members
Articles / Programming Languages / C++

Memory Manager for C++

Rate me:
Please Sign up or sign in to vote.
1.32/5 (17 votes)
28 Jul 2006CPOL2 min read 46.9K   17   12
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)


Written By
Sweden Sweden
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralBoost Pin
Stephen Hewitt29-Jul-06 3:18
Stephen Hewitt29-Jul-06 3:18 
GeneralRe: Boost Pin
Tydia-kun29-Jul-06 3:24
Tydia-kun29-Jul-06 3:24 
GeneralRe: Boost Pin
Stephen Hewitt29-Jul-06 6:29
Stephen Hewitt29-Jul-06 6:29 
There're not complex to use, in fact they’re easier to use then yours – and safer. They provide more functionality such as support for arrays and weak references. And as I mentioned, in the future if you still use C++, you’ll be seeing a lot more of them. But by all means use what you're happy using.

Steve

GeneralRe: Boost Pin
Tydia-kun29-Jul-06 6:33
Tydia-kun29-Jul-06 6:33 
GeneralRe: Boost Pin
Stephen Hewitt29-Jul-06 16:45
Stephen Hewitt29-Jul-06 16:45 
Generalauto_ptr Pin
benjymous24-May-06 22:33
benjymous24-May-06 22:33 
GeneralRe: auto_ptr [modified] Pin
Tydia-kun25-May-06 0:58
Tydia-kun25-May-06 0:58 
GeneralRe: auto_ptr Pin
Stephen Hewitt1-Aug-06 22:08
Stephen Hewitt1-Aug-06 22:08 
GeneralRe: auto_ptr Pin
Tydia-kun2-Aug-06 3:45
Tydia-kun2-Aug-06 3:45 
GeneralRe: auto_ptr Pin
f228-Jul-06 6:34
f228-Jul-06 6:34 
GeneralRe: auto_ptr Pin
Tydia-kun28-Jul-06 6:36
Tydia-kun28-Jul-06 6:36 
GeneralRe: auto_ptr Pin
f228-Jul-06 7:24
f228-Jul-06 7:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.