Técnicas para desenvolvimento e aceleração de códigos científicos


Prof. Edson Borin
Instituto de Computação
Universidade Estadual de Campinas
Raul Baldin
Faculdade de Engenharia Civil, Arquitetura e Urbanismo
Universidade Estadual de Campinas

Atividade Prática: Usando Valgrind para detecção de vazamentos e outros problemas com a memória

Nesta atividade, exercitaremos como utilizar o programa Valgrind e como interpretar seus resultados.

Atividades

Cada atividade possui um pequeno arquivo de código que ilustra alguns exemplos de problemas de memória que podem ser detectados utilizando o Valgrind:

Uso de memória não inicializada

Esta atividade exemplifica um típico erro que programadores cometem, sem perceber: declarar variáveis e depois utilizá-las sem antes inicializá-las.

Muitos compiladores não avisam sobre uso de variáveis não inicializadas, portanto, este problema passa despercebido até que algo estranho aconteça com o programa, por exemplo:
- O programa aborta sem motivo aparente
- O programa mostra resultados diferentes dos esperados
- etc

Comandos para compilar e executar o programa, através do Valgrind:

    g++ -g valgrind_ex01.cpp -o valgrind_ex01
    valgrind --leak-check=full ./valgrind_ex01
      

No caso do gcc/g++, podemos ligar uma opção (-Wuninitialized) para nos alertar sobre uso de variáveis não-inicializadas:

    g++ -g -Wuninitialized valgrind_ex01.cpp -o valgrind_ex01
      

programa: valgrind_ex01.cpp

Leitura/Escrita de memória após desalocá-la (liberá-la)

Esta atividade mostra um outro tipo de problema que pode ser detectado pelo Valgrind: o acesso à memória previamente desalocada pelo programador.

Comandos para compilar e executar o programa, através do Valgrind:

    g++ -g valgrind_ex02.cpp -o valgrind_ex02
    valgrind --leak-check=full ./valgrind_ex02
      

programa: valgrind_ex02.cpp

Leitura/Escrita de memória fora do espaço alocado

Esta atividade mostra um outro tipo de problema que pode ser detectado pelo Valgrind: o acesso à memória além (fora) do espaço alocada pelo programador.

Comandos para compilar e executar o programa, através do Valgrind:

    g++ -g valgrind_ex03.cpp -o valgrind_ex03
    valgrind --leak-check=full ./valgrind_ex03
      

programa: valgrind_ex03.cpp

Leitura/Escrita de memória fora do espaço alocado - vetores

Esta atividade mostra um outro tipo de problema que pode ser detectado pelo Valgrind: o acesso à memória além (fora) do espaço alocada pelo programador, um exemplo utilizando vetores.

Comandos para compilar e executar o programa, através do Valgrind:

    g++ -g valgrind_ex03.1.cpp -o valgrind_ex03.1
    valgrind --leak-check=full ./valgrind_ex03.1
      

programa: valgrind_ex03.1.cpp

Uso errado de malloc/new/new [] vs free/delete/delete [] - chamando 2 vezes o delete sobre um mesmo ponteiro

Esta atividade mostra um outro tipo de problema que pode ser detectado pelo Valgrind: a liberação duplicada de um endereço de memória.

Comandos para compilar e executar o programa, através do Valgrind:

    g++ -g valgrind_ex04.cpp -o valgrind_ex04
    valgrind --leak-check=full ./valgrind_ex04
      

programa: valgrind_ex04.cpp

Uso errado de malloc/new/new [] vs free/delete/delete [] - usando free em endereço alocado por new

Esta atividade mostra um outro tipo de problema que pode ser detectado pelo Valgrind: o uso dos misturado de comandos/operadores para alocação e liberação de memória.

Comandos para compilar e executar o programa, através do Valgrind:

    g++ -g valgrind_ex04.1.cpp -o valgrind_ex04.1
    valgrind --leak-check=full ./valgrind_ex04.1
      

programa: valgrind_ex04.1.cpp

Vazamentos de memória: onde os endereços de memória alocados foram perdidos

Esta atividade mostra um outro problema típico acontece quando os programadores, por exemplo, "reusam" os ponteiros que apontam endereços de memória previamente alocados, sem antes desalocar essa memória, ou guardar em outro ponteiro seu endereço. Assim, perdem definitivamente o(s) endereço(s) alocado(s) anteriormente.

Comandos para compilar e executar o programa, através do Valgrind:

    g++ -g valgrind_ex05.cpp -o valgrind_ex05
    valgrind --leak-check=full ./valgrind_ex05
      

programa: valgrind_ex05.cpp

Arquivo CMake para facilitar a compilação

Comandos utilizados para compilar os exemplos através do uso do CMake:

    ############ 1) Fazer download e Salvar todos os .h e .cpp dentro de um diretório. (acima)
    ############ 2) Fazer download e Salvar o CMakeLists.txt dentro desse mesmo diretório.
    cmake .
    make