schnorr / comp

Disciplina de Compiladores (INF01147) - INF/UFRGS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Vazamento de memória com entradas erradas

schnorr opened this issue · comments

Dúvida de aluno. Estou tentando tratar os memory leaks na etapa 3 do trabalho e fiquei com uma dúvida. Para entradas corretas a minha função libera funciona corretamente, sem deixar qualquer memory leak apontado pelo valgrind; contudo, se passamos uma entrada incorreta, há memory leak. Inicialmente eu pensei que fosse problema com minha função, mas depois notei que mesmo na etapa 2, quando não mexíamos com alocação de memória, o valgrind mostra o mesmo resultado para entradas erradas. Isso é algum problema do bison? Devemos nos preocupar em tratar esses memory leaks que ocorrem para entradas erradas?

O valgrind nos dá o seguinte relatório. A única linha que mudou pras entradas erradas que testei foi a de "checked bytes".

==5015== HEAP SUMMARY:
==5015== in use at exit: 16,458 bytes in 3 blocks
==5015== total heap usage: 5 allocs, 2 frees, 18,506 bytes allocated
==5015==
==5015== Searching for pointers to 3 not-freed blocks
==5015== Checked 70,256 bytes
==5015==
==5015== LEAK SUMMARY:
==5015== definitely lost: 0 bytes in 0 blocks
==5015== indirectly lost: 0 bytes in 0 blocks
==5015== possibly lost: 0 bytes in 0 blocks
==5015== still reachable: 16,458 bytes in 3 blocks
==5015== suppressed: 0 bytes in 0 blocks

O programa não pode ter vazamento de memória mesmo quando a entrada é errada. Ou seja, deve haver procedimento/rotina que realizada a liberação de toda a memória que foi alocada pelo programa quando um erro foi detectado. Tal rotina deve ser chamada após o tratamento do erro, e imediatamente antes do programa terminar (com o código de apropriado).

Na saída fornecida, ressalto o trecho LEAK SUMMARY que contém a seguinte passagem:

==5015== definitely lost: 0 bytes in 0 blocks
==5015== indirectly lost: 0 bytes in 0 blocks
==5015== possibly lost: 0 bytes in 0 blocks
==5015== still reachable: 16,458 bytes in 3 blocks

Perceba que a quantidade de /definitely lost/, /indirectly lost/ e /possibly lost/ estão todos em zero, indicando que não há vazamento de memória. O caso do /still reachable/ indica que a memória é ainda alcançável, portanto não perdida. É possível que o bison ou flex gerem código que aloque memória e mantenha ponteiros apropriados para estas regiões até o final do programa. Isso em si não é um erro e como está fora do alcance de quem os usa, não tem problema.

Se utilizarmos a função yylex_destroy(), definida no header lex.yy.h, podemos liberar a memória alocada pelo flex e bison. A chamada dessa função poderia estar no fim da função main.

@lanahra, obrigado pela dica a respeito do =yylex_destroy()=. De um ponto de vista de projeto, acredito que o código gerado pelo bison deveria chamar yylex_init() no início do código gerado na função yyparse() e yylex_destroy() no final. Isso não acontece, de fato nos obrigando a pelo menos chamar yylex_destroy() após a chamada à yyparse() para evitar:

==5015== still reachable: 16,458 bytes in 3 blocks

E obtendo a mensagem ideal abaixo:

==10409== All heap blocks were freed -- no leaks are possible