memory leak detecting in C++ with/without Visual L

2019-01-22 05:01发布

I want to detect memory leaks of my C++ program in Windows. I read the documentation also on MSDN about mermoy leak detection and I also started using Visual Leak Detector.

I have a doubt about the reporting of the leaks. I am expecting a file name with a line number, but I am always reported the text below. It has all the component of a leak description ( block type, memory address, data, etc..) except for the file name and the line number.

If it is a real leak? If yes do you know why the file/line are not reported? In the meantime I am having a look also at this url

Thanks

Detected memory leaks!
Dumping objects ->
{4723} normal block at 0x04AFB5B8, 8 bytes long.
 Data:  2C 3F 00 00 28 3F 00 00 
{1476} normal block at 0x04AC3B58, 12 bytes long.
 Data:  00 CD CD CD EB 01 75 4C CA 3D 0B 00 
Object dump complete.

7条回答
女痞
2楼-- · 2019-01-22 05:12

I investigated quite some different ways of tracking memory leaks. They all have their advantages but also their disadvantages.

To understand their advantages and disadvantages, we have to understand the different mechanisms and requirements:

  1. How are new, delete, malloc and free intercepted? Some tools use #define to redefine new, delete, malloc and free, but this relies on the correct order of the include files, and may give problems if a class contains e.g. a method called free (as is the case in Qt). The preprocessor will also redefine this method, which may lead to compilation errors or unresolved externals.

    Another way is to overrule the global new and delete operators. This is a much cleaner solution, but fails is you have a 3rd party library that puts a new in the library, but the delete in the header (or vice versa).

  2. How is the source of the call determined. If new,delete,... are intercepted using #define's, often the preprocessor symbols __FILE__ and __LINE__ are uses to get the source of the leak. However, if you have 'generic' functions in your code like e.g. CreateString(), then most of the leaks will be reported in these generic functions, which does not really help you.

    An alternative is to get the call stack at run time. It can be quite easily done using the Windows StackWalk function, but in my experience, this is very very slow. A much faster alternative is to get the base-pointer directly, and to rely on the stack-frame-pointers (you must compile with /Oy- to get the stack-frame-pointers). You can get the frame (base) pointer like this: _asm mov DWORD PTR [FramePtr], ebp. Then simply loop and in the loop get the instruction pointer from ((ADDR *)FramePtr)[1]; and the next frame-pointer fromFramePtr = ((ADDR *)FramePtr)[0];

  3. How to report the leaks at the exact moment. In my case, I want the leaks to be reported at the end of the application, but to be able to do this, you need a leak-reporting mechanism at the end of your application. This means that if you want to report your leaks yourself, you need to rely on global variables being destructed at the end of your application (and report the leaks in ths destructor of the global variable). For server-type applications, you are probably more interested in getting the difference in memory usage between two points in time.

And now the different leak-systems:

  1. C RunTime: reports leaks at the end, but has no decent way of reporting call stacks. Its method of intercepting calls to new,delete,... may cause problems in combinations with 3rd party libraries (like Qt, Boost, ...)

  2. External Microsoft utilities (like GFlags, UMDH,, ...): they seem to be able to only log differences between two points in time. However, the call stack seems to be much better, although the GFlags utility may set flags in the OS that may cause a serious slowdown of your application.

  3. Visual Leak Detector. Seems to correctly find all leaks, but in my case it doesn't work since I have a 3rd party DLL that simply aborts the process at its DllUnload (seems to be a Windows 7 specific problem).

  4. My personal favorite (and people will not agree with me, I'm sure), is to write your own memory manager. Intercepting can be easily done using global new and delete operators (with the possible problems mentioned above), and you can get the call stack as described above. This alternative also relies on being able to have code that is executed at the very last moment in your application.

When choosing an alternative, I found the following aspects very imporant for my situation:

  • I want it to work seemlessly in my application, so that every developer is notified immediately if there is a leak. If you delay leak-checking to a later moment where you use external utilities like Purify, leak-finding will be much harder.
  • I want leaks to be reported at the end of the application, automatically.
  • I want as much as possible information from the leak (the data, the call stack, ...)

Hope this helps.

查看更多
够拽才男人
3楼-- · 2019-01-22 05:13

You should use Valgrind, it's very powerfull and explains properly where are the leaks located in your program. Your program may need to be compiled with gcc, though...

查看更多
啃猪蹄的小仙女
4楼-- · 2019-01-22 05:18

Rational Purify is available as a for-money plugin for VC++, and is a very good leak (and other trouble) detector. I used to use it a lot on Solaris, and it was very easy to use and clear. I've also heard good things from other people about the version for use with Visual Studio, but I've never actually tried that.

FWIW, I suspect that Purify was the inspiration for Valgrind, which has already been mentioned.

查看更多
我只想做你的唯一
5楼-- · 2019-01-22 05:25

This is the output from Visual Studio's own debug CRT, not the output from Visual Leak Detector. Firstly ensure that you're using the current version at Codeplex and that you have #included vld.h in your project. You will get a much more informative output.

查看更多
别忘想泡老子
6楼-- · 2019-01-22 05:33

I got it after debugging a lot of header files.

Here is what has to be done to enable file/line number in the output

#define _CRTDBG_MAP_ALLOC
#define _CRTDBG_MAP_ALLOC_NEW
查看更多
对你真心纯属浪费
7楼-- · 2019-01-22 05:34

Did you compile with debugging information enabled and ensure that the pdb file is available by the leak detector? Without this information it wouldn't be able to provide line numbers.

查看更多
登录 后发表回答