在哪里释放 lex/yacc 程序中使用 _strdup 分配的内存(用于联合)?

Where to free up memory allocated (for union) with _strdup in lex / yacc program?

我在我的 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; }

您确定要释放它吗?你在用你的野牛文件中的语义动作中的字符串做什么?如果您只是存储指针,那么(还)没有什么可以释放的。如果您再复制一份,请立即释放它。

好的,我对 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(); }
   ;

prm:
    foo { $<num>$ = FOO_ID; }
    |
    bar { $<num>$ = BAR_ID; }
    ;

你是 eduffy 建议我应该只在第一种情况下释放原始 char 字符串吗?

在我的程序的其余部分,我总是在调用 _strdup 之前调用 free(在目标上),以清除之前存储的任何内容,这工作正常并且不会导致访问冲突。另外,如果 "yylval->str" 内存未被释放,它会发生什么情况,当 yylval 超出范围时它会被释放吗?我很困惑。

(更新)我想我通过将以下行添加到 yacc / bison 文件找到了解决方案:

%destructor { free($$); } <str>

(另一个更新) ...还添加 free 到适当标记的操作中(假设 strdup 在 "id" 上的 lex 文件中使用)例如

match:
   id prm semicolon { func(); free(); }
   ;