PDA

View Full Version : Memory Manager Class



Doomulation
May 24th, 2006, 16:45
I just thought I'd experiment with a memory manager class, and I decided to post a little prototype I did, so you can try it out, of course...
The basic idea is that it is a normal class which encapsulates a pointer of specific type and contains an internal reference counter. When the counter drops to 0, the object, or memory, is deleted. This happens in the destructor, so the memory should automatically be freed when a function ends. Whatever path the code might take.

To use it... is simple. You simply assign a value with =. Do not reassign a new address to the variables with this, however. Each time you want to, for example, save the memory, you create a new class and assign the old memory object to it via the constructor or via =. The SetNewAddr function works with native pointers. When calling it, you need to specify the address and the reference count. This might be good with memory you don't own or attain elsewhere. But in practice, I wouldn't recommend it.

Here is the code:

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;
}
};
Pointer<T> p;
public:
CMemoryManager()
{
p.pdwRefCount = new DWORD;
*p.pdwRefCount = 0;
p.p = new T;
if (p.p != NULL) (*p.pdwRefCount)++;
}
CMemoryManager(CMemoryManager& rmm)
{
UpdateMemoryManager(rmm);
}
void UpdateMemoryManager(CMemoryManager& rmm)
{
p.p = rmm.p.p;
p.pdwRefCount = rmm.p.pdwRefCount;
(*p.pdwRefCount)++;
}
~CMemoryManager()
{
if (--(*p.pdwRefCount) == 0)
{
delete p.p;
p.p = NULL;
delete p.pdwRefCount;
p.pdwRefCount = NULL;
}
}
void operator = (CMemoryManager* pmm)
{
this->~CMemoryManager(); // When setting a new address, we throw away our old pointer. Therefore, we must decrease the ref count and delete the memory if necessary.
UpdateMemoryManager(*prmm);
}
void operator = (CMemoryManager& rmm)
{
this->~CMemoryManager(); // When setting a new address, we throw away our old pointer. Therefore, we must decrease the ref count and delete the memory if necessary.
UpdateMemoryManager(rmm);
}
void SetNewAddr(T* pNewAddr, DWORD dwRefCount)
{
this->~CMemoryManager(); // When setting a new address, we throw away our old pointer. Therefore, we must decrease the ref count and delete the memory if necessary.
p.p = pNewAddr;
p.pdwRefCount = new DWORD;
*p.pdwRefCount = dwRefCount;
}
Pointer<T>& operator * () { return p; }
T* operator -> () { return p.p; }
};

#define mm CMemoryManager

...And here is a sample of how it's done:


void function_test(mm<int>& p)
{
mm<int> p2 = p;

}

class Mamma
{
public:
int age;
};

int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

mm<int> test;
*test = 100;
int* test2 = new int;
function_test(test);
test.SetNewAddr(test2, 1);

Mamma mom;
mm<Mamma> mom2;
mom2.SetNewAddr(&mom, 1);
mom2 = mom2;

mom2->age = 1;

return 0;
}

Go get! Try it out! It might just be helpful! ^_^
Remember, this is just a little spare time project I made for fun ;)
With this class, you should never have to worry about those pesky pointers anymore!

JeromeB
May 26th, 2006, 22:01
You implemented some kind of Smart Pointer? The STL has a auto_ptr<T> and boost has some specialized Smart Pointers. Why should we use your implementation?

I think it's pretty cool though to make your own smart pointers just to learn more about them, so ... props to you ;)

Doomulation
May 26th, 2006, 22:49
Smart pointers are inferior to my research. This is easy to clone and use and shall never fall short. Besides, it was fun...

JeromeB
May 27th, 2006, 16:15
O'really? :blink:

Doomulation
May 27th, 2006, 16:31
Indeed. Feel free to prove me wrong, though. If you can.

JeromeB
May 27th, 2006, 17:04
I don't want to prove you're wrong, I would like to know why we should use your implementation instead of other Smart Pointers (especially those from the boost-lib)?

Doomulation
May 27th, 2006, 17:52
It it supposed to be better, as I stated :plain:
Its purpose it to use and forget. Allocate memory and forget you've allocated it. As long as you use the container, it will take care of everything. You don't need to think about it.
This is a work in progress, too.

I'm not forcing you to use it either. But you can try it and see if it works better. Otherwise stick with the auto_ptr.
I haven't done any projects using my memory manager yet, but I'll get to it when next I work on something. It will help me improve it and make sure it really works and is easy to use and well... you know. And it's fun, besides.