VS2010 reports false memory leaks for static classes in DLL

The next question is for a memory leak when calling ITK from the Visual Studio library

I clarified the problem with a simple example.

struct A { public: A() { mp_data = new int(0x42); } ~A() { delete mp_data; } int* mp_data; }; A a; 

When such a global class is defined in the DLL, Visual Studio debugs CRT reports that mp_data leaked when the application terminated. Does anyone know a workaround except to disable leak reports?

+6
source share
5 answers

If you call _CrtDumpMemoryLeaks() at the end of the main function, the behavior is expected since mp_data will be deleted after calling _CrtDumpMemoryLeaks() .

You will need to call _CrtDumpMemoryLeaks() after the last static object destructor has been called (or rather, in the last destructor after freeing memory) if you do not want to see these leaks (a rather difficult task, I would not try this).

A cleaner approach is to instead of all static objects in the heap (at the beginning of main ) select all your static objects and free them at the end of main , and then you can call _CrtDumpMemoryLeaks() and you will not see any memory leak.

FYI static objects with constructors and destructors are considered bad anyway, because the order in which they are constructed / desctructed is not deterministic, and because of this, static objects often introduce errors that cannot be easily debugged.

Change Andrew’s comment: You can try to disable automatic calling before _CrtDumpMemoryLeaks by calling _ CrtSetDbgFlag to disable the _CRTDBG_LEAK_CHECK_DF flag. If this works, you can add a static object that calls _CrtDumpMemoryLeaks() in your destructor. To make sure this object is destroyed last, you can use the # pragma init_seg directive (compiler) .

There is no clue if this works ... other than that, all other solutions will most likely require you to change the ITK library (which should be possible, is it an open source library after ??).

+5
source

Any of the following solutions to the problem.

(1) Create a fake DLL dependency on MFC or

(2) Use the solution suggested by smerlin: add this code next to DllMain

 struct _DEBUG_STATE { _DEBUG_STATE() {} ~_DEBUG_STATE() { _CrtDumpMemoryLeaks(); } }; #pragma init_seg(compiler) _DEBUG_STATE ds; 
+2
source

I got the same symptom during the migration of the internal library from the static link to the dynamic linking of the load time, and it turned out that the problem in my case was that the DLL project and the EXE project were associated with different versions of the VC ++ / MFC libraries (one of them was MBCS and the other was Unicode).

In my case, the application and the library used MFC, and the _AFX_DEBUG_STATE destructor, which activated the CRT memory leak dump, was called twice for two separate objects - since DLLs and EXEs are associated with different runtime DLLs, the static state at runtime was effectively duplicated. One of the DLLs will unload and flush leaks too soon and show a bunch of false leaks. Switching both projects to using the same character set allowed sharing a separate relationship at runtime, as well as allowing false leak reports.

In my case, communication with two separate operating modes was unintentional and might have caused other problems. This, obviously, will not occur when using third-party libraries with a well-defined ABI, where you can not control what the CRT library is associated with.

Not sure if this applies in your case, but I would like to publish it in case it will be useful to others.

+2
source

In MFC applications, you can turn off automatic memory leak reset by calling:

 AfxEnableMemoryLeakDump(FALSE); 

This is supported with Visual Studio 2010. For documentation, see here .

0
source

I had the same problems in Visual Studio 2015. I tried all the solutions. The first fake-MFC-dependent solution worked only if you selected the /MT compiler option in your Dll. This way your Dll and the main application will not use the same heap. But often /MD is required, for example. if you want to share the STL container or string objects between the Dll and your main application (Dll border). If /MD , the application and the Dll use the same heap. Therefore, the first fake-MFC-dependent solution did not work for me.

I do not like the second solution by disabling memory leak detection in the main application. When you no longer need a Dll with this call in the destructor, you must remember to re-enable memory leak detection in your application.

I found another solution, so I no longer had false memory errors. You need to use the /delayload linker option for your Dll! All this:-). It worked for me also with the /MD compiler option.

Here you can read something about the Dll border (why use /MD ?). And here you can read something about the features of the CRT compiler in general.

0
source

Source: https://habr.com/ru/post/914044/


All Articles