在lex/yacc中释放()或不释放()[英] to free() or not to free() in lex/yacc

问题描述

你好,

我正在做一个学校项目,我们使用 lex/yacc 编写编译器
对于一种虚构的(类 Java)语言.我已经处理了关于
的所有细节yacc 和 lex 文件,但我还有一个关于动态的问题
字符串的内存分配.当lex文件遇到变量
name,我希望它通过 yylval 将这个传递给 yacc,然后
检索它以添加到语法树.为此,我写了
lex 文件中的以下代码(第三部分),这将保存
yylval 中的变量:

void copy_name(char** dst, char* yy) {
国际化;

//免费(*dst);

//为新字符串分配内存
len = strlen(yy);
*dst = (char*) malloc(len * sizeof(char) + 1);
//复制字符串
strcpy(*dst, yy);
}

它基本上是 strcpy() 的一个包装器,它也分配了一些内存
通过 malloc().

在 lex 文件中,我有这样的东西
{LETTER}({LETTER}|{DIGIT}|"_")* {copy_name(&(yylval.Name) , yytext);
返回(姓名);}

现在我的问题是我是否应该在 copy_name 或
中保留对 free 的调用不是.我会认为我需要这样做,否则新的记忆会是
每次找到新变量时分配,我将面临内存
泄漏.然而,当我取消注释该行时,我开始出现段错误,因为
我无法理解的原因.
任何对 lex/yacc 有更多专业知识的人都可以帮我解决这个问题
有问题吗?

谢谢,
伯克·比兰德

--
通过 http://www.teranews.com
的免费 Usenet 帐户发布

推荐答案

Berk Birand 写道:
你好,

我正在做一个学校项目,我们使用 lex/yacc 编写编译器
对于一种虚构的(类 Java)语言.我已经处理了关于
的所有细节yacc 和 lex 文件,但我还有一个关于动态的问题
字符串的内存分配.当lex文件遇到变量
name,我希望它通过 yylval 将这个传递给 yacc,然后
检索它以添加到语法树.为此,我写了
lex 文件中的以下代码(第三部分),这将保存
yylval 中的变量:

void copy_name(char** dst, char* yy) {
国际化;

//免费(*dst);

//为新字符串分配内存
len = strlen(yy);
*dst = (char*) malloc(len * sizeof(char) + 1);
为什么不 *dst = malloc(len + 1);?

sizeof(char) 根据定义为 1.
>
它基本上是 strcpy() 的一个包装器,它也分配了一些内存
通过 malloc().

在 lex 文件中,我有这样的东西
{LETTER}({LETTER}|{DIGIT}|"_")* {copy_name(&(yylval.Name) , yytext);
返回(姓名);}

现在我的问题是我是否应该在 copy_name 或
中保留对 free 的调用不是.我会认为我需要这样做,否则新的记忆会是
每次找到新变量时分配,我将面临内存
泄漏.然而,当我取消注释该行时,我开始出现段错误,因为
我无法理解的原因.
yylval.Name 是从哪里来的,不是 malloc 分配的,全部
赌注已关闭.您要么必须为您的
分配所有内存使用 malloc 的字符串,或设计另一种方案来复制它们.

--
Ian Collins.

2007 年 4 月 16 日星期一 12:24:10 +1200,Ian Collins 写道:
伯克·比兰德写道:
>len = strlen(yy);
*dst = (char*) malloc(len * sizeof(char) + 1);

为什么不 *dst = malloc(len + 1);?

sizeof(char) 根据定义为 1.
是的,我想我能做到.我想这样会更明确,
但如果它被定义为 1 那么它只是额外的复杂性.

>它基本上是一个strcpy()的包装器,它也通过malloc()分配一些
内存.

在lex文件中,我有这样的东西
{LETTER}({LETTER}|{DIGIT}|"_")* {copy_name(&(yylval.Name) , yytext);
return(NAME);}

现在我的问题是我是否应该在 copy_name
中保留对 free 的调用.我认为我需要这样做,否则每次找到新变量时都会分配新内存
,并且我将面临
内存泄漏.然而,当我取消注释该行时,我开始出现段错误,
出于我无法理解的原因.
yylval.Name 是从哪里来的,不是 malloc 分配的,全部
赌注已关闭.您要么必须为您的
分配所有内存使用 malloc 的字符串,或设计另一种方案来复制它们.
那就是问题所在.yylval 是 yacc 的内部结构变量.在我的
yacc 文件,我设置它的类型如下:

%联合{
整数值;
字符运算符[3];
char* 姓名;
节点类型 *nPtr;
};

现在 Name 是一个字符指针.Lex 不会乱分配
它,但只是将 yylval 声明为一个结构.
的要点这个 copy_name 函数就是做那个分配的.所以我想我们可以
假设我编写的代码将是分配它的代码.
免费使用有意义吗?

谢谢你的回答,
bb

--
通过 http://www.teranews.com
的免费 Usenet 帐户发布

Berk Birand 写道:
2007 年 4 月 16 日星期一 12:24:10 +1200,Ian Collins 写道:
>>
yylval.Name 是从哪里来的,它不是由 malloc 分配的,所有
赌注都关闭了.您要么必须使用 malloc 为您的
字符串分配所有内存,要么设计另一种方案来复制它们.


那就是问题所在.yylval 是 yacc 的内部结构变量.在我的
yacc 文件,我设置它的类型如下:

%联合{
整数值;
字符运算符[3];
char* 姓名;
节点类型 *nPtr;
};

现在 Name 是一个字符指针.Lex 不会乱分配
它,但只是将 yylval 声明为一个结构.
的要点这个 copy_name 函数就是做那个分配的.所以我想我们可以
假设我编写的代码将是分配它的代码.
免费使用有意义吗?
除非已经分配了某些东西,否则不会.如果添加免费原因
崩溃,可能是指针未分配并包含随机值
窒息自由.因此,如果分配是由您完成一次,则永远不会
再次,放弃免费.如果它被(由你)重新分配,那么你有一个
问题,因为无法判断该值是否有效.

--
伊恩·柯林斯.

本文地址:https://www.itbaoku.cn/post/1050471.html