2017-04-16 44 views
0

我試圖在從flex發送的野牛中打印令牌值,但由於某些原因,在某些情況下打印的值是垃圾。從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++代碼並運行它工作正常我不明白爲什麼會發生這樣可以有人發現它的錯誤。

+0

如何創建一個字符串長於字符串數據類型的最大尺寸是多少? – rici

+0

有一個規定來擴展字符串的第一次使用std :: string * s1 = new std :: string(yytext)創建s1的長度;會給s1一段長短的文字。如果我打印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是一個局部變量,但你正試圖返回一個指向它。由於s3將在執行return語句後立即被破壞,指針將被留在未分配的內存中,並且稍後嘗試使用它將會產生不可預知的後果。

無論如何,序列是不必要的。 Flex會將變量yyleng令牌的長度,所以你可以簡單地用它來構建字符串你真的想:

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

如果變量被釋放,它是如何正確工作的長度小於15的字符串,並且不能休息 –

+0

@JeevansaiJinne:有時,未定義的行爲意外地做了你錯誤地期望它做的事情。未定義的行爲可以是任何事情。 – rici

+0

但我嘗試了很多字符串,並在15後只輸出垃圾有多精確 –