Reputation: 481
I've read online that you can free memory in bison like this:
statement:
INTEGER
{
//Do Something
free($1);
}
Where the integer token is returned by flex like this:
[0-9]+ { yylval.integer_value = atoi(yytext); return INTEGER; }
(integer_value is defined as an int)
When I try to free($1)
, I get:
passing argument 1 of ‘free’ makes pointer from integer without a cast
Which makes sense, but I have seen online examples where you can free memory like this. How can I solve this?
Upvotes: 0
Views: 1312
Reputation: 311023
If $1
was the result of a malloc()
or calloc()
or strdup()
, typically as the target value $$
of another production, or a side effect of a lexer action in yylval
, you must free it some time: otherwise you must not.
Upvotes: 0
Reputation: 126448
Most commonly you would need to free memory in an action if it was allocated in an earlier action or the lexer. For example you might have a flex rule:
[a-zA-Z_][a-zA-Z_0-9]* { yylval.id = strdup(yytext); return IDENT; }
this rule allocates memory (the strdup
call), so you would like to ensure that the memory eventually gets freed and does not leak. So you might have
statement: IDENT {
// do something
free($1);
}
Note that you only want to free the memory here if you don't store the pointer in some other data structure that you're going to use (and free) later. It is also tricky to free memory in the presence of error recovery. Bison gives you a special %destructor
directive that can be used to tell the parser how to clean up the parse stack when recovering from an error:
%destructor { free($1); } <id>
This will free the memory allocated/owned by any symbol with a %type
or %token
of <id>
when that symbol is discarded as part of error recovery, or with a YYABORT
or YYACCEPT
directive.
Upvotes: 2