memory leaks

Oct 30, 2011 at 6:49pm
Hi, How can I find (detect) memory leaks in my program? I work on Mac and Linux. Are there any tools that I can use?
Last edited on Oct 30, 2011 at 11:07pm
Oct 31, 2011 at 12:20am
http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/leaks.1.html

Make sure you enable MallocStackLogging too, it's described on that page.
Oct 31, 2011 at 12:58am
There is valgrind for that.
But if you have memory leaks in the first place, you probably need to read and employ this:
http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization
Last edited on Oct 31, 2011 at 12:59am
Nov 7, 2011 at 1:19pm
I can't make any of these to work and I am not sure how to use them.
Here is an example that I would like to use to teach myself how to work with these debuggers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<iostream>

int main()
{
int *mem;

for (int i=0; i<10; ++i)
{
	mem = new int[10]; // memory leak
	for (int i=0; i<10; ++i)
		mem[i] = i;
                
        for (int i=0; i<10; ++i)
        	std::cout << mem[i] << ' ';
        std::cout << std::endl;
}
return 0;
}

How can I find this memory leak with any of these tools (or any other)?
Nov 7, 2011 at 2:17pm
Here's some simple code to catch memory leaks:
1
2
3
4
5
6
7
8
9
// Top of file where main() is called.
#define _CRTDBG_MAP_ALLOC

#include <crtdbg.h>

#ifdef _DEBUG
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif 

Then, at the end of your main, call this:
_CrtDumpMemoryLeaks();
It will write memory leaks to your Output (not console) screen.
Last edited on Nov 7, 2011 at 2:18pm
Nov 7, 2011 at 2:23pm
I assume that it will work for this simple example that I wrote earlier. But how about something more complicated? If I have my code in many different files (both headers and source files) what then? I don't want to go over every single one of them and write this preprocessor directives. Is there an easier way?
Nov 7, 2011 at 2:25pm
Your main calls everything, even if it only contains start(); return 0;
Nov 7, 2011 at 2:32pm
It seems that I have a lot to learn about c++.
What are you saying? If I declare these directives in the file where main() is called than no matter where I use new (even if it is another source file) it will know to dump memory leaks into a file?
Nov 7, 2011 at 2:36pm
It will report memory leaks when the program exits, so you can fix them. It won't do it for you.
(And yes, regardless of which file contains the code that generates them. The compiler laughs at your multi-file design anyway.)
Last edited on Nov 7, 2011 at 2:36pm
Nov 7, 2011 at 2:37pm
You don't need to do anything special to use valgrind. Just call it for a debug build of your program as follows:
valgrind --leak-check=full ./yourProject
It will then give you output such as this:
==3053== Memcheck, a memory error detector
==3053== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==3053== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==3053== Command: ./yourProject
==3053== 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
==3053== 
==3053== HEAP SUMMARY:
==3053==     in use at exit: 400 bytes in 10 blocks
==3053==   total heap usage: 10 allocs, 0 frees, 400 bytes allocated
==3053== 
==3053== 400 bytes in 10 blocks are definitely lost in loss record 1 of 1
==3053==    at 0x4C28658: operator new[](unsigned long) (vg_replace_malloc.c:305)
==3053==    by 0x400861: main (main.cpp:9)
==3053== 
==3053== LEAK SUMMARY:
==3053==    definitely lost: 400 bytes in 10 blocks
==3053==    indirectly lost: 0 bytes in 0 blocks
==3053==      possibly lost: 0 bytes in 0 blocks
==3053==    still reachable: 0 bytes in 0 blocks
==3053==         suppressed: 0 bytes in 0 blocks
==3053== 
==3053== For counts of detected and suppressed errors, rerun with: -v
==3053== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)


This tells you that a total of 400 bytes have been leaked by the new[] in line 9 of main.cpp.
Nov 8, 2011 at 10:35am
leaks only runs on live programs. So to stop your program terminating, I put a sleep command at the end.

I ran the command with

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cleo:~ kev82$ MallocStackLogging=1 ./a.out 
a.out(34248) malloc: recording malloc stacks to disk using standard recorder
a.out(34248) malloc: stack logs being written into /tmp/stack-logs.34248.a.out.h1FrEQ.index
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
a.out(34248) malloc: stack logs deleted from /tmp/stack-logs.34248.a.out.h1FrEQ.index
cleo:~ kev82$


This is then the first bit of the of the output of leaks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
cleo:~ kev82$ leaks a.out
Process:         a.out [34248]
Path:            /Users/kev82/a.out
Load Address:    0x109e81000
Identifier:      a.out
Version:         ??? (???)
Code Type:       X86-64 (Native)
Parent Process:  bash [34053]

Date/Time:       2011-11-08 10:33:20.944 +0000
OS Version:      Mac OS X 10.7.2 (11C74)
Report Version:  7

leaks Report Version:  2.0
Process 34248: 44 nodes malloced for 7 KB
Process 34248: 9 leaks for 432 total leaked bytes.
Leak: 0x109f00960  size=48  zone: DefaultMallocZone_0x109e84000
	0x00000000 0x00000001 0x00000002 0x00000003 	................
	0x00000004 0x00000005 0x00000006 0x00000007 	................
	0x00000008 0x00000009 0x00000000 0x00000000 	................
	Call stack: [thread 0x7fff74727960]: | start | main | operator new[](unsigned long) | operator new(unsigned long) | malloc | malloc_zone_malloc 
Leak: 0x109f00990  size=48  zone: DefaultMallocZone_0x109e84000
	0x00000000 0x00000001 0x00000002 0x00000003 	................
	0x00000004 0x00000005 0x00000006 0x00000007 	................
	0x00000008 0x00000009 0x00000000 0x00000000 	................
	Call stack: [thread 0x7fff74727960]: | start | main | operator new[](unsigned long) | operator new(unsigned long) | malloc | malloc_zone_malloc


Note the call stack tells you exactly where the memory was allocated.
Topic archived. No new replies allowed.