检测dll入口点函数的内存泄漏

时间:2017-04-27 16:06:10

标签: visual-studio visual-c++ dll memory-leaks

我在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入口点函数中找到内存泄漏时,这两者之间有细微差别吗?

1 个答案:

答案 0 :(得分:1)

@HansPassant在评论中回答了我的问题。为了完整起见,我将简单地将他的评论复制在下面作为答案。

  

您认为在调用函数时DLL已加载。那   它不是如何在C ++中工作,你隐式地链接DLL,所以它得到   程序启动时加载。只有LoadLibrary()和/ DELAYLOAD   提供一种即时加载DLL的方法。或者那种动态绑定   用于COM或.NET。所以在你的main()之前创建了泄漏   函数开始运行,无法用_CrtMemCheckpoint()查看。

     

因为在调用myFunction()时没有分配任何东西,就像   _CrtMemDifference()告诉你。分配发生的时间要早​​得多。通过使用调试器说服自己,在DllMain()上设置断点   和main()。而且您很容易看到main()不是第一个代码   开始运行。 - 汉斯帕斯特