Introduction to Valgrind

Get introduced to Valgrind, a powerful tool for detecting memory leaks.

Introduction

It should be clear by now how important it is to avoid memory leaks. Being able to write clean, robust dynamic allocation code is a pretty rare skill.

There are times when we can catch memory leaks, invalid memory accesses, and other memory-related errors just by looking at the code. However, these cases are very few. It becomes hard to keep track of everything in any decently sized code base.

Don’t panic! Some tools can help us, like Valgrind. Valgrind is a Linux-specific tool designed to help detect errors in C and C++ code. The part of Valgrind that we are most interested in is the memcheck tool, which detects memory-related errors (like leaks or invalid memory accesses).

It’s a complex tool, but it’s worth learning how to use, even if at a basic level.

Local setup

This section is optional, as you don’t need to install anything locally. However, we strongly encourage you to keep using Valgrind even after finishing this course. To this end, we show how to install Valgrind in an Ubuntu system. You can search for specific instructions for other distributions.

Open a terminal window and paste the following commands:

sudo apt-get update
sudo apt-get install Valgrind 

It’s that simple!

Note: Valgrind is not available for Windows or macOS.

Educative setup

We already provide an installation of Valgrind on Educative, so you don’t need to do anything.

Here’s how we run Valgrind in the background and how you can run it locally.

Write some C code and compile it. Valgrind is able to show the line where an error occurs if the code is compiled with debug symbols enabled. To enable debug symbols, add the flag -g to gcc. Let’s say the name of the executable file is main.

After the program is compiled, we can run it from Valgrind, like so:

valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --log-file=valgrind_output.txt ./main
  • --leak-check=full: This controls which leaks are displayed.
    • full gives a detailed summary of each leak.
    • summary gives a count of leaks.
  • --show-leak-kinds=all: There are multiple types of leaks that Valgrind can detect, and all means to report all of them.
    • definite
    • indirect
    • possible
    • reachable
    • Note that, in this course, we’ll consider any leak as a serious leak, except suppressed. Our goal is to write leak-free code, even if some leaks are less harmful than others.
  • --log-file=valgrind_output.txt: This writes the Valgrind logs to valgrind_output.txt. If we don’t specify this option the output is printed to stdout.
  • --track-origins=yes: Valgrind can detect the use of uninitialized variables if we specify this option.

Valgrind is pretty complex, but if you want to learn more about what it can do, check the “Appendix 1” section, where you can find more reading resources. This is optional, but it will give you a deeper understanding of all the possibilities offered by Valgrind.

Finding a basic leak

Let’s write a simple allocation with malloc and not free it. We’ll then inspect the logs produced by Valgrind.

Get hands-on with 1400+ tech skills courses.