【问题标题】:Segmentation fault: 11 on unordered set insertion分段错误:无序集插入时为 11
【发布时间】:2022-06-10 20:03:20
【问题描述】:

我不明白为什么这些给定的数字和目标值会显示分段错误

int findind(vector<int> s,int tar, int high , int low ){
    int mid = (high - low)/2;
    if(s.at(mid) == tar){
        return mid;
    }
    else if (tar < s.at(mid)){
        high = mid;
        return findind(s,tar,high,low);
    }
    else{
        low = mid;
        return findind(s,tar,high,low);
    }
}

int main(){
    vector<int> numbers = {-1,0,1,4,5,7};
    int target = 8;
    int id1=-1, id2=-1, N = numbers.size();
    unordered_set<int> us;
    vector<int> ids;
    for (int i = 0; i < N; ++i)
    {   if (numbers[i] == target/2 && target%2 == 0){
            if (i!=N-1 && numbers[i+1] == numbers[i])
            {
                id1 = i;
                id2 = i+1;
                break;
            }
            else{
                us.insert(numbers[i]);
            }
        }

        else if(us.find(target - numbers[i]) == us.end()){
            us.insert(numbers[i]);
        }
        else{
            id1 = i;
            id2 = findind(numbers,target - numbers[i],N,0);
            break;
        }
    }
    if(id1 < id2 ){
        ids.push_back(id1+1);
        ids.push_back(id2+1);
    }
    else{
        ids.push_back(id2+1);
        ids.push_back(id1+1);
    }
    cout<<ids[0]<<" "<<ids[1]<<" ";
    return 0; 
}

崇高文本中的错误是:

enter code hereline 1: 67625 分段错误:11 gtimeout 4s ./TwoSumII-InputArrayIsSorted outputf.in [1.4s 完成,退出码 139]

leetcode 中的错误是:

AddressSanitizer:DEADLYSIGNAL
=================================================================
==30==ERROR: AddressSanitizer: stack-overflow on address 0x7ffd7e8e8fd8 (pc 0x000000334f91 bp 0x00000000001c sp 0x7ffd7e8e8fd0 T0)
==30==ABORTING

如果我输入 numbers = {3,24,50,79,88,150,345} 和 target = 200,也会发生同样的错误。

但如果我在 :

中注释掉 us.insert(numbers[i])
else if(us.find(target - numbers[i]) == us.end()){
            us.insert(numbers[i]);
}

然后把 cout

【问题讨论】:

  • 看起来像无限或非常深递归。 godbolt.org/z/7P5z7ncqY 在调试器中单步调试代码,您可能会找出原因。
  • 在单步执行时,看看你是否可以打开 leetcode 使用的消毒剂,即来自 Retired Ninja 的神螺栓链接的时髦的 -fsanitize=undefined,address。如果你走得太远导致程序崩溃,你至少会得到一个很好的诊断信息,这将有助于下一个调试器运行。
  • 我的问题是递归,你为什么要写一个递归例程?可以迭代地编写相同的函数,或者更好的是 std::lower_boundstd::upper_bound 可以用来代替编写自己的二进制搜索。递归地写东西可能看起来很“酷”,但是这样做的主要缺点之一就是堆栈耗尽。
  • 不是问题的根源,但请使用 const 引用 const vector&lt;int&gt;&amp; s 而不是按值传递向量 vector&lt;int&gt; s,这意味着在每次迭代时制作完整副本。
  • 如果findind 编写正确,它的堆栈深度将为O(log n),这是我接受的递归函数的最大值。使用 O(log n),通常堆栈耗尽几乎是不可能的,这与 O(n) 不同,后者 非常堆栈溢出。

标签: c++ segmentation-fault c++17 unordered-set


【解决方案1】:

我不清楚你的 ma​​in 函数是什么意思,但问题的很大一部分是如果 tarfindind 将永远运行/strong> 不匹配 s 中的任何值,因为退出函数的唯一方法是找到匹配项,满足条件 (s.at(mid) == tar)。否则它将递归,在堆栈上添加另一个条目,最终堆栈将溢出。

int findind(vector<int> s,int tar, int high , int low ){
    int mid = (high - low)/2;
    if(s.at(mid) == tar){
        return mid;
    }
    else if (tar < s.at(mid)){
        high = mid;
        return findind(s,tar,high,low);
    }
    else{
        low = mid;
        return findind(s,tar,high,low);
    }
}

如果在 s 中找不到 tar 的匹配项,您需要决定希望 findind 返回什么值,并且您应该返回该值如果 高 == 低

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 2012-09-27
    相关资源
    最近更新 更多