Sign in to follow this  
cubicool

DLL Memory Question

Recommended Posts

I'm baffled. The best way to explain what's going on is by using some code, so, here goes!
// this is inside a dll file, engine.dll
void Log::GetBuffer(std::string& str) {
   // m_Buffer is an std::stringstream member
   // of the class Log
   str = m_Buffer.str();
}

// ------------------

// this is inside of the calling application
std::string logdata;
LogInstance::GetBuffer(logdata);




Now, inasmuch as I understand it, those two functions should work without error; and, in a way, they do. If I run the application without debugging, everything appears to work fine. However! If I run the app with debugging, when the application closes it throws an unhandled exception (which I know has something to do with how logdata is assigned) of the following: Invalid Address specified to RtlFreeHeap. This looks like some kind of Run Time Library issue, but why? "str" is simply getting a copy of some data that lies inside the dll? I fear this is a hint of a really bad memory leak, but according to the code (and what I understand of C++) it shouldn't be. I tried just returning the entire std::string, but you can't easily pass structures across a dll like that--at least, not STL structures (this is a known issue). I also tried the nasty practice of having a function within the DLL declare some memory on the heap and having the app give the dll a pointer with which the dll would allocate--leaving the cleanup to the app. That was just silly, and didn't work anyways. Can anyone offer some insight as to what's going on? Thanks...

Share this post


Link to post
Share on other sites
What's happening is probably that the DLL and the application are allocating memory from separate heaps. Either one of two things seems to be happening, either the your STL implementation uses the small string optimization, where the initial string contains no actual allocated heap memory. Then when passed to the DLL, the DLL allocates memory in the string from the DLL's heap. When the destructor is called on the string in the application, the address of the pointer is coming from the DLL's heap so isn't properly registered with the application's heap, triggering an error. Alternately, your string's implementation doesn't use the small string opt and the application allocates heap memory for the string in the string's constructor, which is then freed by the DLL when the string's data needs to be expanded. Because the memory was allocated in the applications heap and not the DLL's heap this triggers an error.

At this point I'd like to insert my usual disclaimer that C++ features and DLLs don't mix very well. Especially templates, which is what you're using with std::string even if you don't realize it. (std::string is a typedef for std::basic_string<char>).

At this point there's a few different options to address this. You might consider trying to export std::string from a DLL which would force allocations to come from that DLL's heap. Here's an article demonstrating the syntax for that. You can also try to remove class types from your interfaces, and drop to traditon C style char * based interfaces. Or you can create your own string class entirely implemented in a DLL. It's also possible to instead create an allocator class that lives entirely within the DLL, but this tends to be exceptionally unhappy in practice.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this