0
votes

I build two c++ projects in visual studio 2015. A dll project (myFunction.dll) that implements a function (myFunction). An exe project which simply calls that dll function.

I have a memory leak in dll project (a new without delete in dllmain.cpp) like this:

dllmain.cpp (initilization() under case DLL_PROCESS_ATTACH has memory leak)

#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;
}

Then I was trying to debug my exe project to detect memory leak.

1). If I create memory check points before and after my call to dll function and compare the difference as follows, then visual studio reports no difference, i.e., no memory leaks;

#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). If I call _CtrDumpMemoryLeaks() at the exit of my exe project, then the memory leak from my dll project was captured and reported.

#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;

}    

My question is why isn't the first method capturing memory leak in my dll library if there is clearly new allocated heap memory at checkpoint s2? Shouldn't it be equivalent to the second method? or there is subtle difference between these two when it comes to finding memory leaks from dll entry point functions?

1
You assume that the DLL gets loaded when you call the function. That is not how it works in C++, you implicitly linked the DLL so it gets loaded when your program starts. Only LoadLibrary() and /DELAYLOAD provide a way to load a DLL on-the-fly. Or the kind of dynamic binding used in COM or .NET. So the leak was created before your main() function started running, no way to see that with _CrtMemCheckpoint().Hans Passant
@HansPassant Hans, I did set up the link in my project settings, i.e., addition include directories, linker to .lib files, etc. And my call to the function in my dll library indeed worked. So there is no question that dll was loaded. The question is why the same memory leak was not captured by my first method.Houpigtiger
Because nothing was allocated when you called myFunction(), just like _CrtMemDifference() told you. The allocation happened much earlier. Convince yourself by using the debugger, set a breakpoint on DllMain() and main(). And you'll easily see that main() is not the first code that starts running.Hans Passant
@HansPassant ah ... Hans, you're right. My assumption that dll is only loaded at the time of function call was wrong. You explanation makes sense. Thanks a lot!Houpigtiger

1 Answers

1
votes

@HansPassant answered my question in his comments. For completeness, I'll simply copy his comments below as an answer.

You assume that the DLL gets loaded when you call the function. That is not how it works in C++, you implicitly linked the DLL so it gets loaded when your program starts. Only LoadLibrary() and /DELAYLOAD provide a way to load a DLL on-the-fly. Or the kind of dynamic binding used in COM or .NET. So the leak was created before your main() function started running, no way to see that with _CrtMemCheckpoint().

Because nothing was allocated when you called myFunction(), just like _CrtMemDifference() told you. The allocation happened much earlier. Convince yourself by using the debugger, set a breakpoint on DllMain() and main(). And you'll easily see that main() is not the first code that starts running. - Hans Passant