I have spent the last 24 hours tracking down a heap corruption problem. I think I now know vaguely what the problem is, but it has made it clear I have no idea what I'm doing when it comes to heap usage with DLLs under windows. I am hoping some seasoned windows programmer out there can first look at my sad story below, and then either educate me as to the do's and don'ts of heap usage with DLLs under windows or point me to an article or book that will educate me. I'm not looking to be an expert, but I don't want to hit any more snafus like this one. MY SAD STORY: I'm working on my first windows DLL. I have an exported function that looks much like this one:
void \_\_declspec(dllexport) getCommandString(std::string& commandString);
In case it's not obvious, usage of this function is for the application to pass in a string by reference, then some code in the DLL sets it for you. Perhaps you already know my problem. If you do, YOU are the person I hope to hear from. But I'll finish my sad story for those of you who don't. So I had some application code that called this function, much like this:
void doSomething()
{
std::string commandString;
getCommandString(commandString);
// do some stuff with the string
return;
}
doSomething() fails at the return statement with an assertion failure when memory for commandString was being freed. Digging into the stack trace I found the assertion failure was occuring somewhere in the implementation of this system call:
HeapValidate( \_crtheap, 0, pHdr(pUserData) );
I read the docs for HeapValidate and discovered you could set the thrid arg to NULL to force the entire heap to be validated. So I immediately had the idea of sprinkling my own calls to HeapValidate throughout my code to track down the time when I was corrupting the heap. But then I couldn't figure out where to get the symbol _crtheap. I could see it in the debugger, but couldn't find it declared in any headers that came with VC6. So I says to myself, "I'll just hard code the address since surely _crtheap won't change values from run to run." But this caused me problems too. Eventually I figured out that that value of the global symbol _crtheap was changing within a single run! After some additional contemplation, I says to myself, "Perhaps there is more than one heap for my process!" Through additional experimentation, I now believe that my DLL is allocating and freeing memory