c++ 中的错误:“在抛出 'std::length_error'what() 的实例后调用终止:basic_string::_M_replace_aux”

Posted

技术标签:

【中文标题】c++ 中的错误:“在抛出 \'std::length_error\'what() 的实例后调用终止:basic_string::_M_replace_aux”【英文标题】:Error in c++: "terminate called after throwing an instance of 'std::length_error' what(): basic_string::_M_replace_aux"c++ 中的错误:“在抛出 'std::length_error'what() 的实例后调用终止:basic_string::_M_replace_aux” 【发布时间】:2020-03-16 17:37:12 【问题描述】:

我有一个简单的函数,它接受一串数字并将它们转换为浮点数,函数在下面:

float convertStrToFloatNumber (std::string n) 
    // Converts the number n to a float in the form of 000.000
    if (6 - n.length() > 0) 
        // The representation is with trailing zeros
        n.append(6 - n.length(), '0');
    
    // Insert . at the 3. spot
    n.insert(3, ".");
    return strtof((n).c_str(), 0);

当我使用输入 "030000" 运行时,我如何抛出以下异常:

“在抛出 'std::length_error' what() 的实例后调用终止:basic_string_M_repalce_aux” 我真正感兴趣的是了解错误的最后一部分是什么意思。

【问题讨论】:

你能给我们足够的代码来复制错误吗?我构造了一个 main,我认为它会复制错误,但它运行得非常好。 请稍等,显然源文件更大(G 代码解析器) 长度不是字符数吗? @MartinSigNørbjerg 长度是一个无符号整数,当你“通过”零时,结果会回绕到最大值。 @DavidSchwartz 代码上传到 github 仓库:github.com/Collatz124/GC-TSM 【参考方案1】:

"030000" 不会出现此问题,但任何长度超过 6 个字符的字符串都会出现此问题。

std::string::length() 返回无符号类型。由于整体提升规则,6 被提升为无符号类型,并且您对无符号类型执行减法。无符号类型的下溢导致回绕,因此0 - 1u 等于std::numeric_limits<unsigned>::max()(如果unsigned 是32 位,则等于2^32 - 1 = 4294967295


你可以简单地改变条件的逻辑:

if (n.length() < 6)

或将length 转换为签名类型:

if (6 - static_cast<int>(n.length()) > 0)

【讨论】:

【参考方案2】:

由于n.length() 是无符号的,6 被提升为相同的无符号类型,当长度大于 6 时,减法将回绕并产生一个巨大的正数。

最稳健(也是最短)的解决方案是完全避免减法;

if (n.length() < 6)

    n.resize(6, '0');

【讨论】:

以上是关于c++ 中的错误:“在抛出 'std::length_error'what() 的实例后调用终止:basic_string::_M_replace_aux”的主要内容,如果未能解决你的问题,请参考以下文章

使用 c# 中的 c++ 引用中的引用从 C# 错误调用 C++ 代码

C++中的结构错误

C++ 中的 Vigenere 密码错误

开发 C++ 中的 SIGSEGV(分段错误)错误

这段代码中的错误/错误是啥 c++ 告诉我更正?

如何修复 C++ 中的“分段错误”错误