抛出“std::length_error”实例后调用终止

Posted

技术标签:

【中文标题】抛出“std::length_error”实例后调用终止【英文标题】:Getting terminate called after throwing an instance of 'std::length_error' 【发布时间】:2021-05-20 07:23:24 【问题描述】:

我收到上述错误,我无法调试它的原因。谁能帮我解决这个问题(是什么导致了这个错误)?

问题陈述:寻找最长的公共前缀

来源:https://leetcode.com/problems/longest-common-prefix/

代码(使用分而治之):

#include <iostream>
#include <unordered_map>
#include <string> 
#include <vector>

using namespace std;
class Solution 
public:
    string common_prefix(string left, string right)       
        int minim = min(left.length(), right.length());
        for (int i=0; i<minim; i++)
            if (left[i]!=right[i])
                return left.substr(0, i);
            
        
        return "" ;
    
    string dap(vector<string>& a, int l, int r)
        if (l==r) return a[l];    

        int mid = (l+r)/2;
        string left = dap(a, l, mid);
        string right = dap(a, mid+1, r);
        return common_prefix(left, right);
    
    string longestCommonPrefix(vector<string>& strs) 

        
        return dap(strs, 0, strs.size());
        
    
;


int main()

    Solution s;
    vector<string> st"flower","flow","flight";
    string ans = s.longestCommonPrefix(st);
    cout << ans;

追溯:

Runtime Error
terminate called after throwing an instance of 'std::length_error'
  what():  basic_string::_M_create

输入:

["flower","flow","flight"]

预期输出:

"fl"

链接:https://ide.geeksforgeeks.org/9nKPmtFPd5

【问题讨论】:

请提供minimal reproducible example,包括输入、预期输出以及代码应该做什么 不知何故我期待着这个回复。 Leet 代码在内部提供了一个 main() 来创建 class Solution 的实例并以某种方式调用它(使用某个函数)。只需添加此代码并在本地调试您的应用程序,直到您发现发生了什么。这是非常常见的方式... (What is a debugger and how can it help me diagnose problems?) lr 是 3 的 3 项输入向量时,您可以在 if (l==r) return a[l]; 中访问越界。在调用dap 的序列中,有一个调用dap(3,3) .. @Pygirl 我无法调试它的原因 -- 你为什么无法调试代码?获取真正的 C++ 编译器,在本地编译代码,添加带有数据的main() 在 Linux 上(如果启用),中止的应用程序将产生所谓的核心转储。使用gdb,可以加载应用程序和核心转储以查看调用堆栈,就像调用abort() 之前一样。因此,不需要在调试器中进行新的运行。但是,如果这是一个可重现的错误,那么只需在调试器中重新运行应用程序也可以正常工作。 【参考方案1】:

您的代码中有两个问题。

    r 的初始值为strs.size(),经过几次递归后,您到达if (l == r) return a[l]; 行,而r 仍为初始值。 a[a.size()] 导致未定义的行为。 r 的初始值应为 strs.size() - 1

    common_prefix 中,如果整个较短的字符串是较长字符串的前缀,则返回一个空字符串。您应该返回 left.substr(0, minim)

为了提高效率,您应该在函数参数中使用const string&amp; left 而不是string left,以避免复制字符串。你也可以使用std::string_view 来避免复制字符串:

#include <iostream>
#include <string> 
#include <vector>
#include <string_view>

class Solution 
public:
    std::string_view common_prefix(const std::string_view& left, const std::string_view& right) 
        int minim = std::min(left.length(), right.length());
        for (int i = 0; i < minim; i++) 
            if (left[i] != right[i]) 
                return left.substr(0, i);
            
        
        return left.substr(0, minim);
    

    std::string_view dap(const std::vector<std::string>& a, int l, int r) 
        if (l == r) return a[l];

        int mid = (l + r) / 2;
        std::string_view left = dap(a, l, mid);
        std::string_view right = dap(a, mid + 1, r);
        return common_prefix(left, right);
    

    std::string_view longestCommonPrefix(const std::vector<std::string>& strs) 
        return dap(strs, 0, strs.size()-1);
    
;


int main()

    Solution s;
    std::vector<std::string> st "flower","flow","flight" ;
    std::string_view ans = s.longestCommonPrefix(st);
    std::cout << ans;

【讨论】:

知道了。代码中的逻辑问题。也感谢您提供第二点。从现在开始,我会照顾好它。【参考方案2】:

std::length_error 表示您正在尝试创建比std::string::max_size()更长的字符串

因此,您需要跟踪抛出的字符串。 try/catch

【讨论】:

我知道这个错误,但是是什么导致了这个错误。这就是我卡住的地方。 @Pygirl 字符串长度实际上是用size_t 处理的,它是unsigned 类型的指针大小。使用int 是危险的。如果int 变为(意外)负数,这可能会导致大量无符号数。这些“巨大的无符号数”通常太大而不能用于分配。所以,寻找可疑的int 值是任务...

以上是关于抛出“std::length_error”实例后调用终止的主要内容,如果未能解决你的问题,请参考以下文章

关于在抛出 'std::length_error' 实例后调用终止

抛出“std::length_error”实例后调用终止

在抛出 'std::length_error' what(): basic_string::_S_create 的实例后调用终止

抛出“std::length_error”实例后调用 C++ 终止,what(): basic_string::_M_create

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

理解错误“在抛出 'std::length_error'what() 实例后调用终止:basic_string::_S_create Aborted (core dumped)”