【问题标题】:How to fix 'std::logic_error' what(): basic_string::_M_construct null not valid error?如何修复 'std::logic_error' what(): basic_string::_M_construct null not valid 错误?
【发布时间】:2019-06-23 01:31:26
【问题描述】:

我正在尝试检查输入字符串是字母数字还是更大写或为空。如果输入字符串在上述出现故障的字符串中,我只想返回 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)

这个程序在没有这两种极端情况的情况下运行良好。我无法理解错误并找到解决方法?关于我做错了什么有什么建议吗?

【问题讨论】:

  • 问题是return 0;
  • 同样通过const&amp;传递字符串。
  • 当函数返回一个字符串或什么都不返回时,也许你想返回一个std::optional
  • 是的,我一直在寻找这种类型,因为我想返回两个,正常情况下的字符串,但如果收到故障字符串,则返回整数!
  • 你总是在里面换吗?你改变它是什么意思? const&amp; 更好,如果您可能并不总是需要更改或退回它。

标签: c++


【解决方案1】:

问题在于您的函数中的两个return 0; 语句。该函数返回一个std::string,它没有接受int 作为输入的构造函数。但是,它确实有一个接受const char * 指针的构造函数,0 可以隐式转换为。但是,使用空 char * 指针构造 std::string未定义的行为,并且您的实现选择抛出您的代码中没有捕获的 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

【讨论】:

    【解决方案2】:

    如果要返回 false(或 true),则应将函数的返回类型更改为 bool

    bool myfunc(std::string input) {
    ^^^^
    

    其次,如果您要返回 false,那么这就是您应该返回的内容

    if (!input.size()) return false;
                              ^^^^^
    

    从布尔函数返回 0 不是错误,因为 0 会自动转换为 false,但显然在风格上更好地表达你的意思。

    【讨论】:

    • 我明白这一点,但我的返回类型是 std::string(函数的预期返回)。如果我想将函数的返回类型保留为字符串,您能否建议边缘情况的返回值。
    • 您要求从您的函数中返回布尔值或字符串?这在某些语言中是可能的,但在像 C++ 这样的强类型 语言中却很困难。最好的办法是将函数分成两部分,一个返回 true 或 false 的初始函数,然后是返回字符串的第二个函数,但只有在第一个函数返回 true 时才会调用。
    • @anu 你可以返回std::optional&lt;std::string&gt;,或者在你会返回false的地方抛出一个异常。
    • @anu 在失败时简单地返回一个空白字符串有什么问题? return "";return string();
    猜你喜欢
    • 1970-01-01
    • 2023-01-17
    • 2019-10-26
    • 1970-01-01
    • 2012-07-27
    • 2020-10-15
    • 2019-02-08
    • 2021-04-04
    • 2022-01-11
    相关资源
    最近更新 更多