sas*_*alm 4 c++ dll winapi dynamic-memory-allocation
我今天遇到了这个错误,原因是我在调用后使用了从我的DLL内部分配的字符串FreeLibrary().
这是重现崩溃的简单示例.这在DLL中:
void dllFunc(char **output)
{
*output = strdup("Hello"); // strdup uses malloc
}
Run Code Online (Sandbox Code Playgroud)
这是在加载DLL的EXE中:
void exeFunc()
{
char *output;
dllFunc(&output);
std::string s1 = output; // This succeeds.
FreeLibrary(dll);
std::string s2 = output; // This crashes with access violation.
}
Run Code Online (Sandbox Code Playgroud)
我阅读了文档,FreeLibrary()但是在调用之后我找不到任何关于内存变得无效的内容.
编辑
我刚刚意识到我在使用VS2010工具链进行EXE时使用VS2008工具链(我使用VS2010作为IDE的两者,但你可以从项目设置中选择工具链).为DLL设置工具链到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运行时链接.
请点击这里:http://imgur.com/uld4KYF.png

发生这种情况是因为每个Dll都创建了自己的内存堆(它malloc和它的C朋友,以及new将在内部使用,通常是通过HeapAlloc),并且当Dll被释放时,它的堆也是如此.
有关更多Dll内存警告,请参阅此MSDN文章.除非您使用在所有二进制文件中共享的自定义内存分配器,否则您需要在创建它的模块中保留动态分配的内存(除非您可以100%保证该对象不会超过其创建者).