Visual studio 检测dll入口点函数的内存泄漏
我在VisualStudio 2015中构建了两个C++项目。实现函数myFunction的dll项目myFunction.dll。一个简单调用dll函数的exe项目 我在dllmain.cpp中的一个新的无删除dll项目中有内存泄漏,如下所示: dllmain.cpp在DLL\u进程\u连接存在内存泄漏的情况下初始化Visual studio 检测dll入口点函数的内存泄漏,visual-studio,visual-c++,dll,memory-leaks,Visual Studio,Visual C++,Dll,Memory Leaks,我在VisualStudio 2015中构建了两个C++项目。实现函数myFunction的dll项目myFunction.dll。一个简单调用dll函数的exe项目 我在dllmain.cpp中的一个新的无删除dll项目中有内存泄漏,如下所示: dllmain.cpp在DLL\u进程\u连接存在内存泄漏的情况下初始化 #include "stdafx.h" #include <iostream> #include "TestHelper.h" //header file for a
#include "stdafx.h"
#include <iostream>
#include "TestHelper.h" //header file for a initialization function called when dll process attaches
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
initialization(); //implementation of this function has a new without matching delete
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
然后我试着调试我的exe项目来检测内存泄漏
一,。如果我在调用dll函数之前和之后创建内存检查点,并按如下方式比较差异,则visual studio报告没有差异,即没有内存泄漏
#include "myFunction.h" //header for myFunction.dll
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
int main()
{
_CrtMemState s1;
_CrtMemState s2;
_CrtMemState s3;
_CrtMemCheckpoint(&s1);
myFunction(); //call to dll library whose entry point function causes deallocated memory on the heap
_CrtMemCheckpoint(&s2);
if (_CrtMemDifference(&s3, &s1, &s2))
_CrtMemDumpStatistics(&s3); // no memory difference found; thus no leak
return 0;
}
二,。如果我在exe项目的出口调用_CtrDumpMemoryLeaks,那么就会捕获并报告来自dll项目的内存泄漏
#include "myFunction.h" //header for myFunction.dll
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
int main()
{
myFunction(); //call to dll library whose entry point function causes deallocated memory on the heap
_CrtDumpMemoryLeaks(); //captures and reports memory leak from dll library
return 0;
}
我的问题是,如果检查点s2处有明显的新分配堆内存,为什么第一个方法不捕获dll库中的内存泄漏?它不应该等同于第二种方法吗?或者在从dll入口点函数中查找内存泄漏时,这两者之间有细微的区别?@HansPassant在他的评论中回答了我的问题。为了完整起见,我将在下面简单地复制他的评论作为答案
假设在调用函数时加载了DLL。那个 不是C++中的工作方式,而是隐式链接DLL,使它得到 程序启动时加载。仅LoadLibrary和/或DELAYLOAD 提供一种动态加载DLL的方法。或者是那种动态绑定 在COM或.NET中使用。所以泄漏是在你的主管道破裂之前造成的 函数开始运行,无法通过_CrtMemCheckpoint看到这一点
因为调用myFunction时没有分配任何内容,就像 _我告诉过你。分配发生得更早。通过使用调试器说服自己,在DllMain上设置断点 和main。您很容易就会看到main并不是第一个代码 开始运行汉斯·帕桑
假设在调用函数时加载了DLL。这不是它在C++中的工作方式,而是隐式链接DLL,以便在程序启动时加载它。只有LoadLibrary和/DELAYLOAD提供了动态加载DLL的方法。或者COM或.NET中使用的那种动态绑定。因此,泄漏是在主函数开始运行之前创建的,使用_CrtMemCheckpoint无法看到。@HansPassant Hans,我确实在我的项目设置中设置了链接,即添加了include目录、链接到.lib文件等。我对dll库中的函数的调用确实起到了作用。所以毫无疑问,dll是被加载的。问题是为什么我的第一个方法没有捕获到相同的内存泄漏,因为调用myFunction时没有分配任何内容,就像CrtMemDifference告诉您的那样。分配发生得更早。使用调试器说服自己,在DllMain和main上设置断点。你很容易就会发现main并不是第一个开始运行的代码。@HansPassant啊。。。汉斯,你说得对。我认为dll只在函数调用时加载是错误的。你的解释有道理。谢谢!