bla*_*esa 4 c++ memory-management bison strdup flex-lexer
我或多或少地使用Bison&Flex 1个月,所以如果我没有看到明显的东西(但我认为不是这样),我很抱歉.
我有一个关于使用Flex Bison释放内存的问题.这是我的代码的样子:
parser.l
{DATE} { yylval.str= strdup(yytext);
pair<string,string> newpair = make_pair("DATE",yytext);
myvector.push_back(newpair);
return TOKEN_DATE ;}
Run Code Online (Sandbox Code Playgroud)
这是我的.l文件的一个例子.我将yytext的值复制到yylval.str中.然后我创建一个具有该内容的新对(实际上是键/值),然后我返回bison的令牌日期.我的解析器.y不超过yyparse; 当抓到东西时,它就会打印出来.
我尝试在此运行valgrind,我有关于strdup的多个错误.我知道这个函数使用malloc,但我不知道WHERE和WHEN使用FREE.
我可能猜测它在.y文件中,但在哪里?
test:
TOKEN_DATE { cout << $1 << endl; // here ? and what to free ?}
Run Code Online (Sandbox Code Playgroud)
我真的没有得到所有这些,我真的很感激一个简单明了的解释.
提前致谢,
编辑:
我试过几件事:
test:
TOKEN_DATE TOKEN_TOTO TOKEN_BLABLA { cout << $1 << endl; free($1); free($2);}
| TOKEN_DATE test { cout << $1 << endl, free($1); }
Run Code Online (Sandbox Code Playgroud)
它似乎编译和执行良好,但valgrind仍然告诉我,strdup函数中包含的malloc存在问题.但我不能在flex文件中写自由(yylval.str),否则,野牛不会意识到这个值(如果我理解正确,我试过它不起作用).我真的不知道如何消除这个泄漏的问题.
一旦不再需要,您需要释放复制的字符串.在你相当简单的情况下,你可以在打印之后释放($ 1),但通常情况是解析器将复制的字符串插入到某个数据结构中,在这种情况下,数据结构成为malloc存储的所有者,并且将在析构函数中执行对free的调用.
它与任何其他资源管理问题没有什么不同; 您需要始终清楚谁是已分配资源的所有者,因为所有者有责任在不再需要时释放资源.
内部发生的是bison维护一堆语义值,每个语义值都具有类型YYSTYPE(即"语义类型"),这也是类型yylval.当令牌移动到堆栈上时,bison复制yylval到堆栈顶部.执行对应于一个生产的动作之前,bison安排被称为在生产每个终端和非末端的语义值$1,$2等.(这不是一个副本;各种$x符号与到一个位置的引用替换在bison堆栈上.)
非终端也具有语义值,因为每个动作将值存储到伪变量中$$.(如果操作不这样做,则值$$是不可预测的,但它仍然存在.)操作完成后,bison 从堆栈顶部删除$1,$2...值,然后将伪变量$$复制到堆栈的顶部.它对弹出的值没有任何作用,因此如果它们需要被释放或以其他方式被破坏,则动作必须自己执行此操作.
由于语义值是天真复制的,因此语义类型不应包含任何不易复制的C++对象.
如果您使用%union声明,那么语义类型YYSTYPE是一个union对象,您需要告诉bison哪个联合标记适用于每个终端和非终端.在这种情况下,$$所有的$n都.tag自动附加到它们,并且操作变得更加类型安全.
简单的答案:这取决于。当您使用完内存后,无论何时,都应该释放内存。
更有用的答案:尝试使用尽可能少的内存分配。如果你从来没有malloc任何记忆,你就永远不需要free任何记忆。在您给出的示例中,您对日期进行模式匹配。通常,日期遵循某种格式并且有一定的长度上限;例如,格式“yyyy/mm/dd”包含 10 个字符。yylval如果您能预料到这一点,那么您可以简单地将静态大小的字符数组放入 中,例如 ,而不是创建一个新字符串来保存日期char date[10];。
| 归档时间: |
|
| 查看次数: |
3333 次 |
| 最近记录: |