I'm working on a large C++ project under Visual Studio 2010 and think that there are some memory leaks inside. I tried the approach with including crtdbg.h but it does not help much as I don't see where the leaks occured. Defining new has 2 pitfalls: First it needs to be done in every cpp file which is not really an option, and 2nd it breaks with e.g. Boost. Using new(nothrow) or anything that uses boosts "has_new_operator.h" breaks this. [EDIT: It fails to compile as the redefined "new" has no overloads for something like "nothrow" or the "boost magic"] (Unless one defines "new" after all boost headers including headers referencing boost)
Last but not least: I have singletons. They are implemented using subclasses of the singleton template and a static function variable. One of them is a config container where one registers settings (pairs of strings and ints that are than stored in maps) Since the mem leak dump is called before deallocation of the singleton instance I get a massive amount of leaks for all those strings and the singleton itself.
Any way to have only the real leaks shown or make it dump after static object deallocation?
Which free tools can handle this case?
You can get memory leaks source from
crtdebug
. it won't help you with the boost allocations, unless you compile boost (or any library) in the same way, but for the rest, it will show you allocation file and line.This is how you use properly the
crtdebug.h
:in the top of your
stdafx.h
(or any PCH file) add the following lines:Now in the beginning of your
main
orwinmain
or any entry point to your program add the following lines:Now here a small test I've made:
After a new console program from VS10 called "test": My stdafx.h:
and my test.cpp is:
Output is:
I have used the Visual Leak Detector with quite positive results. It is small and neat, and can be built into your project (assuming you have a running Debug configuration) in a matter of seconds:
https://vld.codeplex.com/
If set-up correctly (which can be done using the installer) then you only have to
in one of your .cpp files for each module - that's it, the header will do the linking for you. You don't have to put it everywhere. Internally the tool uses the CrtDbg, so you have to have a debug build running in order for it to work.
It gives you debugger or text output after each run (if configured using a config file), even when not run through a debugger. It is not the most powerfull tool, but these usually cost some coin ;)
EDIT: There is a possibility to enable the VLD also in non-debug configurations by defining
VLD_FORCE_ENABLE
before including the header. But the results may be tempered with then.EDIT: I have tried a fresh installation of VLD. Note that for VS2013 compilers the v2.4rc2 version must be used (or anything greater v2.3). Version v2.3 only works up until VS2010 compilers.
After installation I created a new project and set-up my include- and library-directories to include the respective VLD folders. After that I used the following code to test memleak reports of singletons (note that this code doesn't make sense, it just proves a point):
With this code, the VLD does not report any leaks because the static auto-variable in
getInstance()
will be destructed upon exit and the elements in the map will be deleted. This must be done nevertheless, even if it's a singleton, otherwise the leaks will be reported. But in this case:If the code in the
getInstance()
is changed to the commented version, then the singleton is never cleared up and the following leaks (amongst others) is reported:You can clearly see the
Count: 100
for this block of code, which is correct.I also edited my
vld.ini
file in the installation directory to have the following set to be enabled:These make sure that a) all duplicate leaks are squashed together to one report with a leak-count (as above, otherwise there would be 100 entries) and the other so that a report-file is dumped in the directory of the application.
So for singletons it works fine as long as you use the static auto-variable approach you are using and do your cleanup in the destructor.
EDIT: Also, the instrumentation can be disabled at specific code pieces. If the above code would be modified like this:
The leaks will never be profiled and not tracked.