最少的野牛/flex生成的代码有内存泄漏 [英] Minimal bison/flex-generated code has memory leak

查看:96
本文介绍了最少的野牛/flex生成的代码有内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在调试大型项目中的内存泄漏时,我发现泄漏的来源似乎是一些由flex/bison生成的代码.我能够使用以下由两个文件sand.lsand.y组成的最小示例来重新创建泄漏:

In debugging a memory leak on a large project, I found that the source of the leak seemed to be some flex/bison-generated code. I was able to recreate the leak with the following minimal example consisting of two files, sand.l and sand.y:

sand.l中:

%{
#include <stdlib.h>
#include "sand.tab.h"
%}

%%
[0-9]+ { return INT; }
. ;
%%

sand.y中:

%{
#include <stdio.h>
#include <stdlib.h>

int yylex();
int yyparse();
FILE* yyin;

void yyerror(const char* s);
%}

%token INT

%%
program:
       program INT { puts("Found integer"); }
       | 
       ;
%%

int main(int argc, char* argv[]) {
    yyin = stdin;
    do {
        yyparse();
    } while (!feof(yyin));
    return 0;
}

void yyerror(const char* s) {
    puts(s);
}

代码是用

$ bison -d sand.y
$ flex sand.l
$ gcc -g lex.yy.c sand.tab.c -o main -lfl

使用valgrind运行程序会出现以下错误:

Running the program with valgrind gave the following error:

8 bytes in 1 blocks are still reachable in loss record 1 of 3
at 0x4C2AC3D: malloc (vg_replace_malloc.c:299)
by 0x40260F: yyalloc (lex.yy.c:1723)
by 0x402126: yyensure_buffer_stack (lex.yy.c:1423)
by 0x400B89: yylex (lex.yy.c:669)
by 0x402975: yyparse (sand.tab.c:1114)
by 0x402EC4: main (sand.y:24)

64 bytes in 1 blocks are still reachable in loss record 2 of 3
at 0x4C2AC3D: malloc (vg_replace_malloc.c:299)
by 0x40260F: yyalloc (lex.yy.c:1723)
by 0x401CBF: yy_create_buffer (lex.yy.c:1258)
by 0x400BB3: yylex (lex.yy.c:671)
by 0x402975: yyparse (sand.tab.c:1114)
by 0x402EC4: main (sand.y:24)

16,386 bytes in 1 blocks are still reachable in loss record 3 of 3
at 0x4C2AC3D: malloc (vg_replace_malloc.c:299)
by 0x40260F: yyalloc (lex.yy.c:1723)
by 0x401CF6: yy_create_buffer (lex.yy.c:1267)
by 0x400BB3: yylex (lex.yy.c:671)
by 0x402975: yyparse (sand.tab.c:1114)
by 0x402EC4: main (sand.y:24)

似乎野牛和/或flex保留了大量的记忆.反正有强迫他们释放的吗?

It seems that bison and/or flex is holding on to a substantial amount of memory. Is there anyway to force them to free it?

推荐答案

默认的flex框架会分配一个输入缓冲区和一个小的缓冲区堆栈,它们永远不会释放.您可以使用 ,但是无法删除缓冲区堆栈. (在您的应用程序中只有8个字节,所以这不是灾难.)

The default flex skeleton allocates an input buffer and a small buffer stack, which it never frees. You could free the input buffer manually with yy_delete_buffer(YY_CURRENT_BUFFER); but there is no way to delete the buffer stack. (It's only 8 bytes in your application, so it's not a disaster.)

如果要编写干净的应用程序,则应生成一个可重入扫描器,它将所有持久数据放入扫描仪上下文对象.您的代码必须分配并释放该对象,释放它将释放所有内存分配. (您可能还想生成一个纯解析器,其工作原理大致相同.)

If you want to write a clean application, you should generate a reentrant scanner, which puts all persistent data into a scanner context object. Your code must allocate and free this object, and freeing it will free all memory allocations. (You might also want to generate a pure parser, which works roughly the same way.)

但是,可重入扫描器具有非常不同的API,因此您将需要使解析器通过扫描器上下文对象.如果还使用可重入(纯)解析器,则需要修改扫描程序操作,因为对于可重入解析器,yylvalYYSTYPE*而不是YYSTYPE.

However, the reentrant scanner has a very different API, so you will need to get your parser to pass through the scanner context object. If you use a reentrant (pure) parser as well, you'll need to modify your scanner actions because with the reentrant parser, yylval is a YYSTYPE* instead of YYSTYPE.

这篇关于最少的野牛/flex生成的代码有内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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