2016-10-24 4 views
0

Когда я выполняю мою программу lex/yacc с valgrind, она обнаруживает утечку памяти. Но я знаю, удастся ли удалить эту утечку памяти. Выход Valgrind является:Почему yacc имеет утечку памяти при выходе?

==10006== 
==10006== HEAP SUMMARY: 
==10006==  in use at exit: 16,458 bytes in 3 blocks 
==10006== total heap usage: 13 allocs, 10 frees, 16,684 bytes allocated 
==10006== 
==10006== 8 bytes in 1 blocks are still reachable in loss record 1 of 3 
==10006== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==10006== by 0x4028FA: yyalloc (lex.yy.c:1852) 
==10006== by 0x402411: yyensure_buffer_stack (lex.yy.c:1552) 
==10006== by 0x400DA9: yylex (lex.yy.c:686) 
==10006== by 0x40312D: yyparse (parser.tab.c:1183) 
==10006== by 0x40462F: parse (Parser.c:10) 
==10006== by 0x4045EB: main (main.c:21) 
==10006== 
==10006== 64 bytes in 1 blocks are still reachable in loss record 2 of 3 
==10006== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==10006== by 0x4028FA: yyalloc (lex.yy.c:1852) 
==10006== by 0x401FA5: yy_create_buffer (lex.yy.c:1387) 
==10006== by 0x400DD3: yylex (lex.yy.c:688) 
==10006== by 0x40312D: yyparse (parser.tab.c:1183) 
==10006== by 0x40462F: parse (Parser.c:10) 
==10006== by 0x4045EB: main (main.c:21) 
==10006== 
==10006== 16,386 bytes in 1 blocks are still reachable in loss record 3 of 3 
==10006== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==10006== by 0x4028FA: yyalloc (lex.yy.c:1852) 
==10006== by 0x401FDC: yy_create_buffer (lex.yy.c:1396) 
==10006== by 0x400DD3: yylex (lex.yy.c:688) 
==10006== by 0x40312D: yyparse (parser.tab.c:1183) 
==10006== by 0x40462F: parse (Parser.c:10) 
==10006== by 0x4045EB: main (main.c:21) 
==10006== 
==10006== LEAK SUMMARY: 
==10006== definitely lost: 0 bytes in 0 blocks 
==10006== indirectly lost: 0 bytes in 0 blocks 
==10006==  possibly lost: 0 bytes in 0 blocks 
==10006== still reachable: 16,458 bytes in 3 blocks 
==10006==   suppressed: 0 bytes in 0 blocks 
==10006== 
==10006== For counts of detected and suppressed errors, rerun with: -v 
==10006== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 

И мой закон:

Chiffre [0-9] 
Lettre [a-zA-Z] 
Alphanum ({Chiffre}{Lettre})+ 

%{ 

#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include "parser.tab.h" 

%} 
%% 
-[a-zA-Z]+ { 
yylval. 
string = strdup(yytext); 
    return OPTION; 
} 

[a-zA-Z0-9_\-./]+ { 
    yylval.string = strdup(yytext); 
    return WORD; 
} 
"||" { 
return OR; 
} 
"|" { 
return PIPE; 
} 
"&&" { 
return AND; 
} 
"&" { 
    return AMPERSAND; 
} 
";" { 
return SEMICOLON; 
} 
"2>" { 
return 
ERR_GREAT; 
} 

">&" { 
return 
GREAT_AMP; 
} 

"2>>" { 
return 
ERR_GREAT_GREAT; 
} 
">>&" { 
return 
GREAT_GREAT_AMP; 
} 
">>" { 
return 
GREAT_GREAT; 
} 

">" { 
return 
GREAT; 
} 

"<" { 
return 
LESS; 
} 

[ \t]+ { 
} 

"\n" { 
return 0; 
} 

%% 

И мой Yacc файл:

%{ 
#include <stdio.h> 
#include "executor/CmdArg.h" 
#include "executor/Command.h" 
#include "print.h" 
int yyerror(const char *msg) { 
    return fprintf(stderr, "YACC: %s\n", msg); 
} 
%} 

%union { 
    int number; 
    char *string; 
}; 
%token<string> WORD 
%token<string> OPTION 
%destructor { 
free($$); 
} <string> 
%token<void> SEMICOLON 
%token OR AND PIPE AMPERSAND GREAT GREAT_GREAT LESS ERR_GREAT ERR_GREAT_GREAT GREAT_AMP GREAT_GREAT_AMP 
%error-verbose 
%% 

pipeline: cmd_args 
background SEMICOLON 
pipeline{ 
end_cmd(SEQUENCING_SEQUENCING); 
} 
| 
cmd_args background 
PIPE pipeline{ 
     end_cmd(SEQUENCING_PIPE); 
} 
| 
cmd_args background 
OR pipeline{ 
     end_cmd(SEQUENCING_OR); 
} 
| 
cmd_args background 
AND pipeline{ 
     end_cmd(SEQUENCING_AND); 
} 
| 
cmd_args background{ 
     end_cmd(SEQUENCING_NOTHING); 
} 
|; 
cmd_args: WORD list_args params io_list{ 
     printdebug("YACC COMMMAND : %s\n", $1); 
    add_arg($1); 
}; 

list_args: OPTION list_args{ 
printdebug ("yacc list arg plusieurs: %s\n", $1); 
add_arg($1); 
}|OPTION{ 
printdebug ("yacc list arg seul : %s\n", $1); 
add_arg($1); 
}|; 

params: WORD params{ 
printdebug ("yacc param plusieurs : %s\n", $1); 
    add_arg($1); 
} 
|WORD { 
printdebug ("yacc param seul: %s\n", $1); 
    add_arg($1); 
}|; 
background: AMPERSAND{ 
     set_background(); 
} 
|; 

io_list: GREAT WORD{ 
    set_io(GREAT,$2); 
}|GREAT_GREAT WORD{ 
    set_io(GREAT_GREAT,$2); 
} LESS WORD{ 
    set_io(LESS,$2); 
}| ERR_GREAT WORD{ 
    set_io(ERR_GREAT,$2); 
}| ERR_GREAT_GREAT WORD{ 
    set_io(ERR_GREAT_GREAT,$2); 
}| GREAT_AMP WORD{ 
    set_io(GREAT_AMP,$2); 
}| GREAT_GREAT_AMP WORD{ 
    set_io(GREAT_GREAT_AMP,$2); 
}|; 


%% 

struct CmdArg *temp; 
void set_io(enum yytokentype tokentype, char* file){ 

} 
void set_background() { 
    temp->_background = 1; 
} 
void add_arg(char* s){ 
    if (!temp)temp = new_cmdArg(); 
    cmdarg_add_argument(temp,s); 
    free(s); 
} 
void end_cmd(Sequencing seq){ 
    temp->_seq=seq; 
    command_add_cmdArg(temp, seq); 
    free_cmdArg(temp); 
    temp = NULL; 
} 

Спасибо за вашу помощь.

+0

На самом деле это бизон (не yacc), так как он использует специальные указания bison. –

ответ

2

== 10006 == УТЕЧКИ РЕЗЮМЕ:

== 10006 == определенно потерял: 0 байт в 0 блоков

== 10006 == косвенно потерял: 0 байт в 0 блоков

== 10006 == возможно потеряно: 0 байт в 0 блоков

== 10006 == еще достижима: 16,458 байт в 3-х блоков

== 10006 == подавлено: 0 байтов в 0 блоках

Не освобождая доступную память, вполне нормально для большинства программ. Поскольку на выходе все еще есть указатель, это не утечка.

+0

Хорошо, я благодарю вас. – Oneill

+2

Я нашел yylex_destroy для завершения программы с помощью 0 утечки. – Oneill