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

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

我在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 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只在函数调用时加载是错误的。你的解释有道理。谢谢!