Home CPSC 340

Valgrind

Objective

To learn about the Valgrind debugging tool.

Overview

Valgrind is a tool for debugging programs for memory leaks, and other errors.

Unlike gdb, which is interactive, Valgrind runs your code from start to finish. During execution, Valgrind will check your program for errors such as:


Usage

To use Valgrind, just run the "valgrind" command, followed by the program you want to run - including any command line inputs:


$ valgrind ./a.out

Valgrind will be much more helpful if you compile with the "-g" option which is also used by gdb:


$ clang++ -g code.cpp
$ valgrind ./a.out

Undefined Behavior

Valgrind will detect when you try to use an uninitialized value This is a common bug in C++ programs.

The following code:


#include <iostream>
using namespace std;

int main() {
    bool condition;

    if (condition) {
        cout << "true\n";
    } else {
        cout << "false\n";
    }

    return 0;
}
Produces:

==13676== Conditional jump or move depends on uninitialised value(s)
==13676==    at 0x400803: main (x.cpp:7)

Bounds Checks

Valgrind will also bounds-check arrays when you read them. The following program:


#include <iostream>
using namespace std;

int main() {
    int* array = new int[10];

    for (int i = 0; i <= 10; i++) {
        array[i] = i;
    }

    for (int i = 0; i <= 10; i++) {
        cout << array[i] << endl;
    }

    delete [] array;

    return 0;
}
Gives the output:

==13813== Invalid read of size 4
==13813==    at 0x400998: main (x.cpp:12)
==13813==  Address 0x5a1c068 is 0 bytes after a block of size 40 alloc'd
==13813==    at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13813==    by 0x40093D: main (x.cpp:5)

Memory Leaks

Valgrind will also inform you of any memory leaks in your program. For the following code:


#include <iostream>
using namespace std;

int main() {
    int* array = new int[10];

    for (int i = 0; i < 10; i++) {
        array[i] = i;
    }

    for (int i = 0; i < 10; i++) {
        cout << array[i] << endl;
    }


    return 0;
}

Valgrind says:


==17545== HEAP SUMMARY:
==17545==     in use at exit: 40 bytes in 1 blocks
==17545==   total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==17545== 
==17545== LEAK SUMMARY:
==17545==    definitely lost: 40 bytes in 1 blocks
==17545==    indirectly lost: 0 bytes in 0 blocks
==17545==      possibly lost: 0 bytes in 0 blocks
==17545==    still reachable: 0 bytes in 0 blocks
==17545==         suppressed: 0 bytes in 0 blocks
==17545== Rerun with --leak-check=full to see details of leaked memory
==17545== 
==17545== For counts of detected and suppressed errors, rerun with: -v
==17545== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)

Exercise

For this lab, you will use valgrind to debug the program 07-list.cpp. This program uses a doubly linked list to store the numbers 1 - 25, remove the odd numbers, and then print the list to the screen. For simplicity, unused functions are removed.

This program runs fine, but contains two issues, your job is to figure out what they are:

Copyright © 2018 Ian Finlayson | Licensed under a Creative Commons Attribution 4.0 International License.