title: Why yacc have memory leak at exit?
body: <p>when I execute my lex/yacc program with valgrind, it find memory leak. But I would know if it's possible to delete this memory leak. The output of valgrind is: </p>
  
  <pre><code>==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)
  </code></pre>
  
  <p>And my lex: </p>
  
  <pre><code>Chiffre [0-9]
  Lettre [a-zA-Z]
  Alphanum ({Chiffre}{Lettre})+
  
  %{
  
  #include &lt;string.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #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;
  }
  "&amp;&amp;" {
  return AND;
  }
  "&amp;" {
      return AMPERSAND;
  }
  ";" {
  return SEMICOLON;
  }
  "2&gt;" {
  return
  ERR_GREAT;
  }
  
  "&gt;&amp;" {
  return
  GREAT_AMP;
  }
  
  "2&gt;&gt;" {
  return
  ERR_GREAT_GREAT;
  }
  "&gt;&gt;&amp;" {
  return
  GREAT_GREAT_AMP;
  }
  "&gt;&gt;" {
  return
  GREAT_GREAT;
  }
  
  "&gt;" {
  return
  GREAT;
  }
  
  "&lt;" {
  return
  LESS;
  }
  
  [ \t]+ {
  }
  
  "\n" {
  return 0;
  }
  
  %%
  </code></pre>
  
  <p>And my yacc file: </p>
  
  <pre><code>%{
  #include &lt;stdio.h&gt;
  #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&lt;string&gt; WORD
  %token&lt;string&gt; OPTION
  %destructor {
  free($$);
  } &lt;string&gt;
  %token&lt;void&gt; 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-&gt;_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-&gt;_seq=seq;
      command_add_cmdArg(temp, seq);
      free_cmdArg(temp);
      temp = NULL;
  }
  </code></pre>
  
  <p>Thank you for your help. </p>