我在visual studio 2015中构建了两个c ++项目。一个实现函数(myFunction)的dll项目(myFunction.dll)。一个只调用dll函数的exe项目。
我在dll项目中有一个内存泄漏(dllmain.cpp中没有删除的新内存),如下所示:
dllmain.cpp(在DLL_PROCESS_ATTACH内存泄漏的情况下,initilization())
#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项目来检测内存泄漏。
1)。如果我在调用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;
}
2)。如果我在我的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入口点函数中找到内存泄漏时,这两者之间有细微差别吗?
答案 0 :(得分:1)
您认为在调用函数时DLL已加载。那 它不是如何在C ++中工作,你隐式地链接DLL,所以它得到 程序启动时加载。只有LoadLibrary()和/ DELAYLOAD 提供一种即时加载DLL的方法。或者那种动态绑定 用于COM或.NET。所以在你的main()之前创建了泄漏 函数开始运行,无法用_CrtMemCheckpoint()查看。
因为在调用myFunction()时没有分配任何东西,就像 _CrtMemDifference()告诉你。分配发生的时间要早得多。通过使用调试器说服自己,在DllMain()上设置断点 和main()。而且您很容易看到main()不是第一个代码 开始运行。 - 汉斯帕斯特