O Valgrind é uma excelente ferramenta para resolver dois problemas em seus programas: vazamento de memória e acesso a posições inválidas de memória (o que pode levar a segmentation fault).
A seguir apresentamos alguns exemplos de como usar o Valgrind.
Considere o seguinte programa que lê 10 números e depois imprime-os na ordem inversa.
Esse programa tem um vazamento de memória: o vetor alocado não é desalocado antes do programa terminar.
Isso pode ser detectado com o Valgrind. Suponha que o arquivo compilado (usando a opção -g do gcc) chama programa e que você tem um arquivo de teste chamado entrada.
No terminal, execute:
Você verá o seguinte resultado.
No começo o Valgrind dá algumas mensagens padrões, depois vemos a saída do programa (substituído aqui por …) e depois o Valgrind avisa que houveram bytes perdidos na seções HEAP SUMMARY e LEAK SUMMARY. Perdemos 40 bytes em de um bloco (uma chamada de malloc). Mais do que isso, eles avisa que o malloc responsável pelo vazamento foi no arquivo programa.c, na linha 5 (programa.c:5).
Suponha que você corrija o código, liberando o vetor:
Então a saída do valgrind será:
Ou seja, nesse caso não há vazamento de memória!
O Valgrind também avisa de erros de acesso a posições inválidas. Por exemplo, o seguinte programa tenta escrever o número 1 na posição 0 do vetor, mas o vetor começa como NULL, isto é, tentamos escrever na posição 0x0 (NULL) da memória.
Neste caso, o Valgrind nos avisa que estamos fazendo uma escrita ilegal na linha 6 do programa.c. Assim é possível saber o que causou o segmentation fault.
Veja outro exemplo, onde alocamos um vetor de 8 posições, mas tentamos usar até 10 posições.
A saída do valgrind indica o problema da escrita na posição errada do vetor linha 7 (invalid write of size 4), indicando onde o bloco de memória mais próximo foi alocado (um bloco de 32 bytes alocado em programa.c:5) e indica também o problema da leitura na posição errada (invalid read of size 4).