Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Freeing memory allocated in a different DLL

I have an EXE file using a DLL file which is using another DLL file. This situation has arisen:

In DLL file 1:

class abc
{
    static bool FindSubFolders(const std::string & sFolderToCheck, 
                               std::vector< std::string > & vecSubFoldersFound);
}

In DLL file 2:

void aFunction()
{
    std::vector<std::string> folders;
    std::string sLocation;
    ...
    abc::FindSubFolders(sLocation, folders)
}

In release mode, everything works fine. But in debug mode, I come up with an assertion failure in the destructor of one of the std::strings in the folders vector (when folders goes out of scope at the end of aFunction):

dbgheap.c : line 1274

/*
 * If this ASSERT fails, a bad pointer has been passed in. It may be
 * totally bogus, or it may have been allocated from another heap.
 * The pointer MUST come from the 'local' heap.
 */
_ASSERTE(_CrtIsValidHeapPointer(pUserData));

I assume this is because the memory has been allocated on DLL file 1's heap, but is being freed in DLL file 2.

The comment in dbgheap.c seems pretty insistent that this is a problem.

Why is this such a problem, when it seems to work fine if I just ignore it? Is there a non-assertion-failing way of doing this?

like image 341
Smashery Avatar asked Oct 28 '09 02:10

Smashery


2 Answers

As sean has already said, the release build simply ignores that delete statement, so the best you can hope for is a memory leak.

If you have control over how both DLL files are compiled, make sure to use the Multi-threaded Debug DLL (/MDd) or Multi-threaded DLL (/MD) settings for the runtime library. That way, both DLL files will use the same runtime system and share the same heap.

The downside is that you need to install the runtime system together with your application (Microsoft offers an installer for that). It will work fine on your development machine since Visual Studio installs that runtime system too, but on a freshly installed machine it will report missing DLL files.

like image 199
Hans Avatar answered Sep 30 '22 15:09

Hans


Most likely, the release build has the same problem, but release builds don't assert. They just ignore the problem. You might never see an issue. Or you might see data corruption. Or you might see a crash. Maybe only your users will experience bugs that you are simply not able to reproduce.

Don't ignore CRT assertions.

You should always use the appropriate deallocator (the one that matches the allocator used to begin with). If you are using static CRT libraries in your DLL files, the DLL files are using different heaps. You can not deallocate memory across heaps. Allocate and deallocate a block of memory using the same heap.

If you are using shared CRT libraries in your DLL files, then they should be using the same heap and you can allocate in one DLL file and deallocate in another.

like image 41
sean e Avatar answered Sep 30 '22 13:09

sean e