哪里可以释放Bison/Flex中的内存? [英] Where to free memory in Bison/Flex?

查看:226
本文介绍了哪里可以释放Bison/Flex中的内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Bison& Flex或多或少会持续1个月,因此,如果我看不到明显的东西(但我不认为是这样),我感到抱歉.

I'm using Bison & Flex for 1 month more or less, so I'm sorry if I don't see something obvious (but I don't think it is).

我对使用Flex Bison释放内存有问题.这是我的代码:

I have a problem about freeing memory with Flex Bison. Here is what my code looks like:

 parser.l

 {DATE}      { yylval.str= strdup(yytext);
             pair<string,string> newpair = make_pair("DATE",yytext);
             myvector.push_back(newpair);
              return TOKEN_DATE ;}

这是我的.l文件的示例之一.我将yytext的值复制到yylval.str中.然后我创建一个具有该内容(实际上是键/值)的新对,然后返回野牛的令牌日期. 我的解析器.y不只是yyparse;当发现某些东西时,它只会打印出来.

This is one of the example of my .l file. I copy the value of yytext into yylval.str. Then I create a new pair with that content (key/value, actually), then I return the token date for bison. My parser .y is not more than yyparse; and when something is caught, it just prints it.

我尝试对此运行valgrind,并且在strdup上存在多个错误.我知道此函数使用malloc,但我不知道在何处以及何时使用FREE.

I tried to run valgrind on this and I have multiple errors concerning strdup. I know this function uses malloc, but I have no idea WHERE and WHEN to use FREE.

我可能猜它在.y文件中,但是在哪里?

I probably guess it's in the .y file, but where ?

 test:
      TOKEN_DATE                 { cout << $1 << endl; // here ? and what to free ?}

我并没有真正了解所有这些信息,我非常希望获得一个简单明了的解释.

I don't really get all of this, I would really appreciate a simple and clear explanation.

预先感谢

我尝试了一些类似的事情:

I tried several things like:

 test:
      TOKEN_DATE TOKEN_TOTO TOKEN_BLABLA { cout << $1 << endl; free($1); free($2);}
    | TOKEN_DATE test { cout << $1 << endl, free($1); }

似乎可以很好地编译和执行,但是valgrind仍然对我说,strdup函数中包含的malloc存在问题.但是我无法在flex文件中编写free(yylval.str),否则,野牛将无法识别该值(如果我正确理解,我会尝试不起作用).我真的不知道如何解决这个泄漏的问题.

It seems to compile and execute good, but valgrind still says to me that there is a problem with the malloc contained in the strdup function. But I cannot write free(yylval.str) inside the flex file, otherwise, bison will not be aware of the value (if I understood correctly, I tried it doesn't work). I really have no idea on how to remove this leaking problem.

推荐答案

一旦不再需要复制的字符串,则需要释放它.在您相当简单的情况下,您可以在将它打印出来后释放($ 1),但通常情况是解析器将复制的字符串插入某些数据结构中,在这种情况下,数据结构成为malloc存储的所有者,并且免费电话将在析构函数中执行.

You need to free the copied string once you no longer need it. In your rather simple case you could free($1) after printing it out, but it is often the case that the parser inserts the copied string into some datastructure, in which case that datastructure becomes the owner of the malloc'd storage, and the call to free will be performed in a destructor.

与其他任何资源管理问题并没有真正的不同;您需要始终清楚谁是分配资源的所有者,因为所有者有责任在不再需要时释放资源.

It's not really different from any other resource management issue; you need to always be clear who is the owner of an allocated resource because the owner has the responsibility for releasing the resource when it is no longer needed.

内部发生的情况是bison维护了一个语义值堆栈,每个语义值都具有类型YYSTYPE(即语义类型"),也就是yylval的类型.当令牌移到堆栈上时,bisonyylval复制到堆栈顶部.在执行与产品对应的动作之前,bison将产品中每个终端和非终端的语义值安排为$1$2等.(这不是副本; $x符号将替换为对bison堆栈上某个位置的引用.)

What's going on internally is that bison maintains a stack of semantic values, each of which has the type YYSTYPE (i.e. "semantic type"), which is also the type of yylval. When a token is shifted onto the stack, bison copies yylval onto the top of the stack. Before executing an action corresponding to a production, bison arranges for the semantic values of each terminal and non-terminal in the production to be known as $1, $2, etc. (This is not a copy; the various $x symbols are replaced with a reference to a location on the bison stack.)

非终端也具有语义值,因为每个动作都会将值存储到伪变量$$中. (如果操作不执行此操作,则$$的值是不可预测的,但它仍然存在.)操作完成后,bison从堆栈顶部删除了$1$2 ...值,然后将伪变量$$复制到堆栈的顶部.它不会对弹出的值做任何事情,因此,如果需要释放或破坏它们,则操作必须自己执行.

Non-terminals also have semantic values, because each action stores a value into the pseudo-variable $$. (If the action doesn't do this, the value of $$ is unpredictable, but it still exists.) After the action finishes, bison removes the $1, $2... values from the top of the stack, and then copies the pseudo-variable $$ onto the top of the stack. It does not do anything to the values which were popped, so if they need to be freed or otherwise destructed, the action must do this itself.

因为语义值是天真的复制的,所以语义类型不应包含任何不能轻易复制的C ++对象.

Because semantic values are copied naively, the semantic type should not contain any C++ object which is not trivially copyable.

如果使用%union声明,则语义类型YYSTYPEunion对象,并且您需要告诉bison哪个联合标记适用于每个终端和非终端.在这种情况下,$$和所有$n会自动附加正确的.tag,并且操作在某种程度上更安全​​.

If you use the %union declaration, then the semantic type YYSTYPE is a union object, and you need to tell bison which union tag applies to each terminal and non-terminal. In that case, $$ and all the $n have the correct .tag appended to them automatically, and the actions become somewhat more type-safe.

这篇关于哪里可以释放Bison/Flex中的内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆