问题描述
我今天遇到这个bug,原来是因为在调用 FreeLibrary()
之后,我使用从我的DLL 中分配的字符串 / p> 这是一个简单的例子来重现崩溃。这在DLL中:
void dllFunc(char ** output)
{
* output = strdup (你好); // strdup使用malloc
}
这是在EXE中加载DLL: / p>
void exeFunc()
{
char * output;
dllFunc(& output);
std :: string s1 = output; //这成功了
FreeLibrary(dll);
std :: string s2 = output; //这会导致访问冲突崩溃。
}
我阅读了 FreeLibrary() code>但是在调用后,我无法找到有关内存变得无效的内容。
修改
我刚刚意识到,我使用VS2008工具链作为DLL,而使用VS2010工具链的EXE(我使用的是VS2010作为IDE,但是您可以从项目设置中选择工具链)。将工具链设置为VS2010,以便卸载崩溃。
如果您选择静态链接到MSVCRT(C运行时)库,你会得到你所描述的行为。如果您的EXE和DLL动态链接到MSVCRT DLL但使用不同的版本,同样的事情也会发生。或者如果它们匹配相同的版本,但是一个使用DEBUG,另一个正在使用RETAIL。换句话说,内存只是用于进行分配的MSVCRTxxx.dll的生命周期。我刚刚看到你对你的问题的更新 - 是的,混合和匹配VS 2008和2010之间的CRT是崩溃的确切原因。
如果你的DLL和EXE动态链接到MSVCRT DLL的相同的版本,然后共享内存堆,并避免出现问题。
标准做法是这样的:如果您导出的DLL函数返回任何需要释放或释放的任何东西,那么标准做法是提供从DLL导出的附加功能来处理去分配。
您可以从项目中的C / C ++项目设置的代码生成页面配置EXE和DLL的C Runtime链接。
图片:
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.
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
这篇关于为什么在FreeLibrary()之后,从DLL内部分配的内存变得无效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!