0

我正在尝试在从 flex 发送的野牛中打印令牌值,但由于某种原因,打印的值在某些情况下是垃圾。

法典代码:

\".*\" {
std::string* s1 = new std::string(yytext);
    std::string s2 = *s1;
    std::string s3 = s2.substr(1,s2.size() - 2);
    yylval.s = &s3;

    return VARIABLE;
}

野牛代码:

    %union{
            std::string *s;
    };

%type <s> expr

expr : VARIABLE { caps($1); }

void caps(std::string *str){
    std::string str1 = *str;

    for(std::string::size_type i=0;i<str1.length();i++)
            std::cout << str1[i];
}

如果我输入长度小于 15 个字符的字符串,则输出正常,但如果长度超过它,则会打印垃圾。

如果我隔离 c++ 代码并运行它工作正常,我不明白为什么会发生,所以有人可以找到其中的错误。

4

1 回答 1

4

以下是未定义的行为:

std::string* s1 = new std::string(yytext);
std::string s2 = *s1;
std::string s3 = s2.substr(1,s2.size() - 2);
yylval.s = &s3;
return VARIABLE;

s3是一个局部变量,但您正试图返回一个指向它的指针。由于s3将在return语句执行后立即销毁,因此指针将悬空在未分配的内存中,稍后尝试使用它会产生不可预知的后果。

无论如何,这个顺序是不必要的。Flex 将变量设置yyleng为标记的长度,因此您可以简单地使用它来构造您真正想要的字符串:

yylval.s = new std::string(yytext + 1, yyleng - 2);
return VARIABLE;
于 2017-04-16T17:13:14.983 回答