2017-04-16 5 views
0

フレックスから送られたバイソンのトークン値を印刷しようとしていますが、何らかの理由で印刷された値がごみになることがあります。フレックスからバイソンへの値渡し

のlexコード:

\".*\" { 
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]; 
} 

I入力15文字未満の長さを持つ文字列、それは細かい出力が、長さは、それを超えた場合にはゴミがプリントされた場合。

私はC++コードを分離して実行してもうまく動作しますが、なぜそれが起こっているのか分からないので、誰かが間違いを見つけることができます。

+0

がどのように文字列データ型の最大サイズよりも長い文字列を作成するのですか? – rici

+0

std :: string * s1 = new std :: string(yytext)を使用して、s1を作成したときに最初に文字列の長さを拡張するための規定があります。 s1にyytextの長さを与えていたはずです。もし私がs1の値を表示していれば、それは正しく印刷されています。そうでなければ、最大デフォルトサイズは11です。これは非常に短いです。 –

+1

11は文字列の最大サイズではありません。文字列の最大サイズは 'std :: basic_string :: max_size()'です。これは11よりかなり大きいです:http://ideone.com/7z5oDh – rici

答えて

3

次は未定義の動作です:

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はローカル変数ですが、それへのポインタを返すようにしようとしています。 returnステートメントが実行されるとすぐにs3が破棄されるため、ポインタは割り当てられていないメモリにぶら下がり、後で使用しようとすると予測できない結果になります。

いずれにしても、シーケンスは不要です。 Flexは、トークンの長さに変数yylengを設定しますので、あなたは、単にそれはあなたが実際にしたい文字列を構築するために使用することができます。

yylval.s = new std::string(yytext + 1, yyleng - 2); 
return VARIABLE; 
+0

変数が割り当て解除されていれば、どのように正しく動作していますか?長さが15より短く、休憩に失敗する –

+0

@JeevansaiJinne:時には未定義の動作は、予期せず誤って行うと思われる動作をします。定義されていない動作は何でもかまいません。 – rici

+0

しかし、私は多くの文字列を試してみました.15の後には、どれだけ正確にガベージが出力されますか? –

関連する問題