Why does memory allocated from inside a DLL become invalid after FreeLibrary()?

纵饮孤独 提交于 2019-12-07 09:31:58

问题


I had this bug today which turned out to be because I use a string allocated from inside my DLL after calling FreeLibrary().

This is a simple example reproducing the crash. This goes in DLL:

void dllFunc(char **output)
{
    *output = strdup("Hello"); // strdup uses malloc
}

This is in the EXE that loads the DLL:

void exeFunc()
{
    char *output;
    dllFunc(&output);
    std::string s1 = output; // This succeeds.
    FreeLibrary(dll);
    std::string s2 = output; // This crashes with access violation.
}

I read the documentation of FreeLibrary() but I couldn't find anything about memory becoming invalid after it's called.

Edit

I just realized that I had been using VS2008 toolchain for the DLL while using VS2010 toolchain for the EXE (I was using VS2010 as IDE for both, but you can select the toolchain from the project settings). Setting the toolchain to VS2010 for the DLL as well removed the crash.


回答1:


If you choose static linking with the MSVCRT (C Runtime) library, you will get the behavior you describe. Same thing also happens if your EXE and DLL are dynamically linked to an MSVCRT DLL, but are using different versions. Or if they are matched to the same version, but one is using DEBUG and the other is using RETAIL. In other words, memory is only as good as the lifetime of the MSVCRTxxx.dll used to make the allocation. I just saw your update to your question - yes, mixing and matching the CRT between VS 2008 and 2010 is the exact reason for the crash.

If both your DLL and EXE are dynamically linked to the same version of the MSVCRT DLL, then you share the memory heap and you avoid the problem you are having.

The standard practice is this: If your exported DLL function returns anything that needs to be "freed" or "released" later, then standard practice is to provide an additional function exported out of the DLL to handle de-allocations.

You can configure both the EXE and DLL's C Runtime linkage from the Code-Generation page for the C/C++ project settings in your project.

Picture here: http://imgur.com/uld4KYF.png




回答2:


This occurs because each Dll creates its own memory heap (which malloc and its C friends, along with new will use internally, generally via HeapAlloc), and when the Dll is freed, so is its heap.

Refer to this MSDN article for more Dll memory caveats. unless you are using a custom memory allocator, shared across all your binaries, you need to keep dynamically allocated memory within the module that created it (unless you can 100% guarantee that the object will not outlive its creator).



来源:https://stackoverflow.com/questions/15300812/why-does-memory-allocated-from-inside-a-dll-become-invalid-after-freelibrary

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!