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.
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
.
I would like to build on RageD's great answer by providing 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.
sudo apt-get install valgrind #mainly Ubuntu sudo yum install valgrind #RHEL, CentOS, Fedora, etc.
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).
valgrind --leak-check=full \ --show-leak-kinds=all \ --track-origins=yes \ --verbose \ --log-file=valgrind-out.txt \ ./executable exampleParam1
This will produce a report at the end of executing your program that (hopefully) looks like this:
HEAP SUMMARY: in use at exit: 0 bytes in 0 blocks total heap usage: 636 allocs, 636 frees, 25,393 bytes allocated All heap blocks were freed -- no leaks are possible ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
So, you have a memory leak, and Valgrind isn't saying anything meaningful. Perhaps, something like this:
5 bytes in 1 blocks are definitely lost in loss record 1 of 1 at 0x4C29BE3: malloc (vg_replace_malloc.c:299) by 0x40053E: main (in /home/Peri461/Documents/executable)
Let's take a look at the C code I wrote too:
#include int main() { char* string = malloc(5 * sizeof(char)); //ERROR: not freed! return 0; }
Well, there were 5 bytes lost. How did it happen? The error report just says main
and malloc
. 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 using gcc
here):
gcc -o executable -std=c11 -Wall main.c #suppose it was this at first gcc -o executable -std=c11 -Wall -ggdb3 main.c #add -ggdb3 to it
Now look at what Valgrind did with our debug build:
5 bytes in 1 blocks are definitely lost in loss record 1 of 1 at 0x4C29BE3: malloc (vg_replace_malloc.c:299) by 0x40053E: main (main.c:4)
Valgrind pointed us to the exact line of code causing the memory leak!
gdb
perhaps), and look for precondition/postcondition errors.60 bytes in 1 blocks are definitely lost in loss record 1 of 1 at 0x4C2BB78: realloc (vg_replace_malloc.c:785) by 0x4005E4: resizeArray (main.c:12) by 0x40062E: main (main.c:19)
And the code:
#include #include struct _List { int32_t* data; int32_t length; }; typedef struct _List List; List* resizeArray(List* array) { int32_t* dPtr = array->data; dPtr = realloc(dPtr, 15 * sizeof(int32_t)); //doesn't update array->data return array; } int main() { List* array = calloc(1, sizeof(List)); array->data = calloc(10, sizeof(int32_t)); array = resizeArray(array); free(array->data); free(array); return 0; }
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 leave resizeArray
without telling array->data
where the array was moved to.
1 errors in context 1 of 1: Invalid write of size 1 at 0x4005CA: main (main.c:10) Address 0x51f905a is 0 bytes after a block of size 26 alloc'd at 0x4C2B975: calloc (vg_replace_malloc.c:711) by 0x400593: main (main.c:5)
And the code:
#include #include int main() { char* alphabet = calloc(26, sizeof(char)); for(uint8_t i = 0; i
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.
1 errors in context 1 of 1: Invalid read of size 1 at 0x400602: main (main.c:9) Address 0x51f90ba is 0 bytes after a block of size 26 alloc'd at 0x4C29BE3: malloc (vg_replace_malloc.c:299) by 0x4005E1: main (main.c:6)
And the code:
#include #include int main() { char* destination = calloc(27, sizeof(char)); char* source = malloc(26 * sizeof(char)); for(uint8_t i = 0; i
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.
You can run:
valgrind --leak-check=full --log-file="logfile.out" -v [your_program(and its arguments)]