1. ホーム
  2. c++

[解決済み] std::logic_error' what(): basic_string::_M_construct null not valid エラーを修正する方法?

2022-01-28 20:55:21

質問

入力文字列が英数字か大文字以上か空白かを調べようとしています。もし入力文字列が上記のような誤動作をする文字列であれば、単にfalse/0を返したいだけで、それ以外は正常に動作しているプログラムの残りの部分で作業したいのです。私のプログラムのチャンクは、与えられた問題である。

std::string myfunc(std::string input){
    std::string b="";

    if (!input.size()) return 0;
    for (int i = 0; i < input.size(); i++){

        if ( input[i] < 'a' || input[i] > 'z'|| isalpha(input[i]) || isupper(input[i]) ) return 0;
    }
    b = input;
    //just copy the input string for now.
    return b;
}

で、この関数を次のように呼び出します。

int main(){
    std::string input="Somthing";
    std::cout << myfunc(input)<< std::endl;
    return  0;
}

以下のエラーが発生しましたか?

terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_M_construct null not valid
Aborted (core dumped)

このプログラムは、この2つのエッジケースがなければ、うまく動作します。私はこのエラーを理解し、その修正を見つけることができないのですか?何が間違っているのか、何か提案はありますか?

解決方法を教えてください。

問題は、2つの return 0; ステートメントを使用しています。この関数は std::string を受け入れるコンストラクタはありません。 int を入力とします。しかし、このコンストラクタは const char * のポインタがあり、0は暗黙のうちに変換される。しかし std::string をヌル char * ポインタは 未定義の動作 を投げることを選択し、実装は std::logic_error 例外が発生しますが、あなたのコードではキャッチしていません。

この場合、代わりに単純に空白の文字列を返します。

std::string myfunc(const std::string &input){
    if (input.empty()) return "";
    for (int i = 0; i < input.size(); ++i){
        char ch = input[i];
        if ( !((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) ) return "";
    }
    return input;
}

呼び出し側は、必要であれば、戻り値が空であるかどうかをチェックすることができます。

if (myfunc(input).empty())
    // error, do something
else
    // OK, do something else

を返す関数とどっちがいいんだろう? bool ではなく std::string :

bool isvalid(const std::string &input){
    if (input.empty()) return false;
    for (int i = 0; i < input.size(); ++i){
        char ch = input[i];
        if ( !((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) ) return false;
    }
    return true;
}

// if you still needed this function for something...
std::string myfunc(const std::string &input){
    if (!isvalid(input)) return "";
    return input;
}

if (!isvalid(input))
    // error, do something
else
    // OK, do something else