2016-03-30 6 views
0

私はいくつかの解析例外をスローしています。しかし、例外は壊れた文字列を取る..?例外的に文字列が壊れていますか?

//Parse exception 
class ParseException : public exception { 
public: 
    //Constructor 
    //Arguments: 
    // Str: Message 
    // Pos: Position 
    ParseException(string Str, int Pos) { 
     msg = Str; 
     pos = Pos; 
    } 

    //Get what happened(From exception) 
    //Returns: 
    // Message with position 
    virtual const char* what() const throw() { 
     string str = msg; 
     str += " at " + to_string(pos); 
     return str.c_str(); 
    } 
private: 
    string msg; //Message 
    int pos; //Position 
}; 

これは例外クラスです。

throw ParseException("Mismatched bracket", P.Pos); 

この例外がスローされたとに行くされています:

try { 
    Parse(p); 
} 
catch (ParseException e) { // <<< Here 
    cerr << "ParseException: " << e.what() << endl; 
} 

そして、何私が取得することである:私のコードに問題が

ParseException: ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌ 

があり、私はこのようなこの例外をthrowed ?またはVisual Studio(またはコンパイラ)の問題?

+3

'str'は' what() 'に対してローカルです。関数が終了すると破棄されます。 'str.c_str()'を返すと、未定義の動作が発生します。 –

答えて

3

As noted in the commentsの場合、ローカルstringc_strを返すことはできません。例外自体にwhat値のstringキャッシュを格納すると意味があります。 the char* returned by what needs to live as long as the exception objectなので、例外のキャッシングは合理的です。

class ParseException : public exception { 
public: 
    //Constructor 
    //Arguments: 
    // Str: Message 
    // Pos: Position 
    ParseException(string Str, int Pos) : msg(std::move(Str)), pos(Pos) {} 

    //Get what happened(From exception) 
    //Returns: 
    // Message with position 
    virtual const char* what() const throw() { 
     // Lazily populate what so it's not populated until called 
     if (_what.empty()) { 
      _what = msg + " at " + to_string(pos); 
     } 
     return _what.c_str(); 
    } 
private: 
    string msg; //Message 
    int pos; //Position 
    string _what; 
}; 

はまた、あなたがコンストラクタで値を計算するので、whatは、互換性のnothrow(C++標準ライブラリの例外をマッチング)のまま。

関連する問題