Click to See Complete Forum and Search --> : Using my own Memory Manger


TheNomad
August 11th, 2010, 03:01 PM
Hello all,

I wrote my own memory manager. ATM it can handle new, delete, malloc, realloc, calloc and free (no new\delete [] as I don't need it).
Putting this aside, it works flawlessly (at least to my needs) and has a bit more detections than the windows one (I think 2 extra, since the one in the Win API is pretty packed up and doesn't miss much :) + I added more info like the line it allocated, deallocated, function that deallocated it etc. ).

... Anyway... my problem: even though I use my own memory blocks, allocation\deallocation functions, Windows still calls its own functions.

Basically, the flow is this:
1. xfree(myPointer)
2. cMemoryManager:: Deallocate( ... lots of stuff like pointer, pointer name, line etc.)
3. ... some checks like if it was previously deallocated, if it is null (this is just for clean code, I know it is not critical to free a NULL pointer or so say most), if it is a valid block etc etc
4. IF it was allocated by my manager, keep it for later checks, free on shutdown
5. IF it wasn't (dunno who sent the pointer, maybe another DLL or some inner windows stuff), then do CRT free (myPointer) cos I don't wanna track it

The problem comes when I CRT malloc (basically the main allocation from inside my manager) or CRT free it (when it is from another source). Basically, instead of calling CRT free(), it calls Win API free() which calls free_dbg().

I also called _CrtSetDbgFlag(0); and undef-ed _CRTDBG_MAP_ALLOC (and yes it is in the proper header), yet the first EVER call to free() throws a not-a-heap-manager-memory-block-error and a breakpoint gets called.

Engine flow:

1. WinMain ()
2. create the mem manager - by create i mean it calls new and creates an instance that has OS specific stuff like the statistics, the real alloc\dealloc is done with statics; ignore this architecture pls :)
3. create the debug manager
4. each log entry can be done on separate "channels" so i can track the errors easier like "File Manager", "Memory Manager" etc. so I use a struct called sDebugMessage()
5. I create a channel, free its string param (that would be the name) and the exception appears

As you have guessed we're talking about _DEBUG defined.

Code:


typedef tDynamicArray <sDebugChannel*> arrDebugChannel;
arrDebugChannel g_vChannels;

struct sDebugChannel
{
tString Name;
tByte Flags;
tByte ID;

sDebugChannel() : Name(NULL), Flags(0), ID(0) implemented;
};

#define ADD_CHANNEL(channel, flags) g_pDebugManager->AddChannel((channel), (#channel), (flags))

void cDebugManager :: OpenDefaultChannels (tUndefined)
{
ADD_CHANNEL(CHANNEL_DEBUG_MANAGER, CFLG_Default);
}

void cDebugManager :: AddChannel (tByte ID, tString Name, tByte Flags)
{
// format the name
if (strStr(Name, "_") != NULL)
{
tInt position;

// this is similar to an InStr() func that returns the position of a strStr()
position = strSubstr(Name, "CHANNEL_");

if (position != INDEX_INVALID)
{
tString temp = Name;
Name = strMid(Name, (position + 8));
free(temp); // problem is here
}

strSentence(Name, '_');
strReplace(Name, "_", " ");
}

// add the channel
channel = xnew sDebugChannel();

channel->ID = ID;
channel->Name = Name;
channel->Flags = Flags;

g_vChannels.Add(channel);
}


The problem: because #CHANNEL_DEBUG_MANAGER becomes "CHANNEL_DEBUG_MANAGER" (the pointer 'temp'), this gets sent as the channel name and is later converted to "Debug Manager". strMid() does an unorthodox memcpy() and returns the mid part (so the original string is untouched... - ignore this, I plan to rewrite it anyway since memcpy() is not meant to do this, but I needed a quick solution). Anyway, free() gets called and intercepted by my mem manager.
Since it wasn't a string that was allocated by me by done via macros, it is ignore by my mem manager and freed normally via the CRT free(), which is unfortunately replaced by the Win API free() which calls free_dbg().

Since it isn't allocated via the Win Heap Manager either it throws the not-a-heap-pointer error.

What is the best way to handle this ? Preferably without replacing #channel with a param for strings and allocating the string before adding the channel; if all else fails, I will use this method.

I wanted to actually disable the debug heap manager :(
And I can't seem to. What am I missing ?

Related to the title is the fact, as said, I wanna disabled the Win mem mngr and use my own, which would also solve my problem.


Thanks in advance !

mani3355
August 12th, 2010, 12:11 AM
I also called _CrtSetDbgFlag(0); and undef-ed _CRTDBG_MAP_ALLOC (and yes it is in the proper header), yet the first EVER call to free() throws a not-a-heap-manager-memory-block-error and a breakpoint gets called.
thanks

regards,
phe9oxis,
http://www.guidebuddha.com

TheNomad
August 12th, 2010, 12:40 AM
Did you want to say something to my quote ? I don't see anything :confused: