我在yacc / bison文件中定义了以下联合结构:
%union
{
int num;
double dbl;
char ch;
char *str;
}
在我的lex / flex文件中,我有以下匹配:
[a-zA-Z][a-zA-Z0-9"_"]* { yylval->str = _strdup(yytext); return id; }
我的问题是,我在哪里放置代码以释放“str”?
free(yylval->str);
假设这没关系。请注意,如果我在字符串重复之前放置“free”,则会出现访问冲突:
[a-zA-Z][a-zA-Z0-9"_"]* {
free(yylval->str);
yylval->str = _strdup(yytext);
return id; }
答案 0 :(得分:1)
你确定需要释放它吗?您在bison文件中的语义操作中对字符串做了什么?如果你只是存储指针,那么就没有任何东西可以释放(还)。如果您再制作一份,请立即将其释放。
答案 1 :(得分:0)
好的,我在yacc / bison文件中使用“str”(char *)做了两件事: 1.我使用strdup制作另一个副本(稍后我将副本释放) 2.我没有使用“char *”(字符串)显式做任何事情,例如,在lex / flex文件中:
";" { return semicolon; }
"foo"|"FOO" { return foo; }
"bar"|"BAR" { return bar; }
...并在yacc / bison文件中:
%token<str> cmd foo bar
...
line:
cmd prm semicolon { func($2); }
;
prm:
foo { $<num>$ = FOO_ID; }
|
bar { $<num>$ = BAR_ID; }
;
你是否认为我应该只在第一种情况下释放原始的字符串?
在我的程序的其余部分,我总是在调用_strdup之前调用free(在目标上),清除之前存储的任何内容,这样可以正常工作并且不会导致访问冲突。如果没有释放“yylval-&gt; str”内存会发生什么,当yylval超出范围时它会被释放吗?我很困惑。
(更新)我想我通过在yacc / bison文件中添加以下行找到了解决方案:
%destructor { free($$); } <str>
(另一次更新) ...还为相应的令牌添加了自由(假设在“id”的lex文件中使用了strdup),例如。
match:
id prm semicolon { func($2); free($1); }
;