How do I use valgrind to find the memory leaks in a program?
Please someone help me and describe the steps to carryout the procedure?
I am using Ubuntu 10.04 and I have a program a.c
, please help me out.
How do I use valgrind to find the memory leaks in a program?
Please someone help me and describe the steps to carryout the procedure?
I am using Ubuntu 10.04 and I have a program a.c
, please help me out.
You can run:
Try this:
valgrind --leak-check=full -v ./your_program
As long as valgrind is installed it will go through your program and tell you what's wrong. It can give you pointers and approximate places where your leaks may be found. If you're segfault'ing, try running it through
gdb
.How to Run Valgrind
I would like to build a more verbose explanation for how to use Valgrind effectively and how to resolve memory leaks. Not to insult the OP, but for those who come to this question and are still new to Linux—you might have to install Valgrind on your system.
Valgrind is readily usable for C/C++ code, but can even be used for other languages when configured properly (see this for Python).
To run valgrind, pass the executable as an argument (along with any parameters to the program).
This will produce a report at the end of executing your program that (hopefully) looks like this:
I have a leak, but WHERE?
So, you have a memory leak, and Valgrind isn't saying anything meaningful. Perhaps, something like this:
Let's take a look at the C code I wrote too:
Well, there were 5 bytes lost. How did it happen? The error report just says
main
andmalloc
. In a larger program, that would be seriously troublesome to hunt down. This is because of how the executable was compiled. We can actually get line-by-line details on what went wrong. Recompile your program with a debug flag (I'm usinggcc
here):Now with this debug build, Valgrind points to the exact line of code allocating the memory that got leaked! (The wording is important: it might not be exactly where your leak is, but what got leaked. The trace helps you find where.)
Techniques for Debugging Memory Leaks & Errors
IndexOutOfBoundsException
type problems.gdb
perhaps), and look for precondition/postcondition errors.A Look at Common Leaks and Errors
Watch your pointers
And the code:
As a teaching assistant, I've seen this mistake often. The student makes use of a local variable and forgets to update the original pointer. The error here is noticing that
realloc
can actually move the allocated memory somewhere else and change the pointer's location. We then leaveresizeArray
without tellingarray->data
where the array was moved to.Invalid write
And the code:
Notice that Valgrind points us to the commented line of code above. The array of size 26 is indexed [0,25] which is why
*(alphabet + 26)
is an invalid write—it's out of bounds. An invalid write is a common result of off-by-one errors. Look at the left side of your assignment operation.Invalid read
And the code:
Valgrind points us to the commented line above. Look at the last iteration here, which is
*(destination + 26) = *(source + 26);
. However,*(source + 26)
is out of bounds again, similarly to the invalid write. Invalid reads are also a common result of off-by-one errors. Look at the right side of your assignment operation.The Open Source (U/Dys)topia
How do I know when the leak is mine? How do I find my leak when I'm using someone else's code? I found a leak that isn't mine; should I do something? All are legitimate questions. First, 2 real-world examples that show 2 classes of common encounters.
Jansson: a JSON library
This is a simple program: it reads a JSON string and parses it. In the making, we use library calls to do the parsing for us. Jansson makes the necessary allocations dynamically since JSON can contain nested structures of itself. However, this doesn't mean we
decref
or "free" the memory given to us from every function. In fact, this code I wrote above throws both an "Invalid read" and an "Invalid write". Those errors go away when you take out thedecref
line forvalue
.Why? The variable
value
is considered a "borrowed reference" in the Jansson API. Jansson keeps track of its memory for you, and you simply have todecref
JSON structures independent of each other. The lesson here: read the documentation. Really. It's sometimes hard to understand, but they're telling you why these things happen. Instead, we have existing questions about this memory error.SDL: a graphics and gaming library
What's wrong with this code? It consistently leaks ~212 KiB of memory for me. Take a moment to think about it. We turn SDL on and then off. Answer? There is nothing wrong.
That might sound bizarre at first. Truth be told, graphics are messy and sometimes you have to accept some leaks as being part of the standard library. The lesson here: you need not quell every memory leak. Sometimes you just need to suppress the leaks because they're known issues you can't do anything about. (This is not my permission to ignore your own leaks!)
Answers unto the void
How do I know when the leak is mine?
It is. (99% sure, anyway)
How do I find my leak when I'm using someone else's code?
Chances are someone else already found it. Try Google! If that fails, use the skills I gave you above. If that fails and you mostly see API calls and little of your own stack trace, see the next question.
I found a leak that isn't mine; should I do something?
Yes! Most APIs have ways to report bugs and issues. Use them! Help give back to the tools you're using in your project!
Further Reading
Thanks for staying with me this long. I hope you've learned something, as I tried to tend to the broad spectrum of people arriving at this answer. Some things I hope you've asked along the way: How does C's memory allocator work? What actually is a memory leak and a memory error? How are they different from segfaults? How does Valgrind work? If you had any of these, please do feed your curiousity:
malloc
, C's memory allocator