在递归函数中使用按引用调用返回多个值时出现分段错误

Getting segmentation fault while using call by reference to return multiple values in recursive function

提问人:user22021739 提问时间:6/12/2023 更新时间:6/12/2023 访问量:56

问:

问题是在数组中找到最大和最小元素并返回它们的差值。我提到了 GeeksforGeeks 上关于这个问题的社论。我使用了 tournament 方法,在这种方法中,我们将任何具有两个以上元素的数组分成 2 个部分,并找到这两个数组的最大值和最小值,然后在比较这些最终值后返回答案。这里列出的官方解决方案,使用结构对。我想使用按引用值调用来做到这一点。

最初,我尝试使用以下函数返回 2 个值:

int r1,r2= Sample(a,high,low)

这是错误的(因为我们只能从函数中返回 1 个值) 所以我尝试像这样传递引用:

void halfarrsol(int arr[], int low, int high, int &mi, int &ma){
int mid, min,max;
if(low==high){
    mi=ma=arr[low];
}
if(high==low+1){
    mi=arr[low], ma=arr[high];
    if(arr[low]>arr[high]){
        mi=arr[high];
        ma=arr[low];
    }
}
else {
    mid=(low+high)/2;
    halfarrsol(arr, low,mid,mi,ma);
    int minl=mi, maxl=ma;
    halfarrsol(arr, mid+1,high,mi,ma);
    int minr=mi, maxr=ma, fin=minl;
    if(minl>minr){
        fin= minr;
    }
    int fax=maxl;
    if(maxl<maxr){
        fax=maxr;
    }
    mi= fin;
    ma=fax;
}
}

这个想法是,当我调用该函数时,最小值和最大值(mi 和 马)将可用。 我认为可能会把事情搞砸的一个明显错误是

halfarrsol(arr, low,mid,mi,ma);
      int minl=mi, maxl=ma;

我在这里尝试的是将获得的 mi 和 马 值(对于这个半数组)存储在“minl”和“maxl”变量中。这有效吗? 整个代码给出一个分段错误,以及超时:受监视的命令转储核心错误。 我不确定我到底搞砸了什么,或者这种方法是否完全错误。我希望能够在不使用 Struct Pair 的情况下解决这个问题,也无需使用另一个类并创建对象。 还有一些解决方案,例如使用元组来存储最小值和最大值,但我认为它们更适用于我们有许多返回值的情况,因为这里我只使用 2 个值。 有没有办法使用引用调用递归地解决这个问题?
如果需要,您可以在此处查看驱动程序代码

C++ 递归 分段-故障 按引用传递

评论

0赞 463035818_is_not_an_ai 6/12/2023
仅当可以初始化变量时,才应声明变量。 需要扫描整个函数以检查它是否正确初始化并且根本没有使用。midmaxmin
0赞 Ted Lyngmo 6/12/2023
为此使用递归似乎是错误的。如果你的数组有数百万个元素,那么这个递归就会非常深入。
0赞 463035818_is_not_an_ai 6/12/2023
并尝试使用描述性名称。与其删除单个字母以获得不同的名称,不如添加更多字母以明确变量的用途。
2赞 Jesper Juhl 6/12/2023
什么是调试器,它如何帮助我诊断问题?
2赞 molbdnilo 6/12/2023
您的“官方”解决方案很可能是错误的;GeeksForGeeks 在很大程度上是垃圾,不值得你为此付出代价。

答:

0赞 Jiraiya 6/12/2023 #1

如果你专注于逻辑,这个错误就不容易弄清楚。你的逻辑或多或少是正确的,问题是当 时,它将无限期地递归调用函数,因为你没有返回你没有使用过的函数。更改为以下内容:low == highelse ifhigh == low + 1

...
if(low==high){
    mi=ma=arr[low];
}
else if(high==low+1){
    mi=arr[low], ma=arr[high];
    if(arr[low]>arr[high]){
        mi=arr[high];
        ma=arr[low];
    }
}
else {
...

评论

0赞 user22021739 6/12/2023
我不清楚有什么帮助......它如何代表返回语句?else if
0赞 Jean-Baptiste Yunès 6/12/2023 #2

递归永不停止。在第一种情况下,您忘记结束它:

if(low==high){
    mi=ma=arr[low];
}

然后它输入第二个 if,其中条件为 false,然后转到 else...

至少更改为:

if(low==high){
    mi=ma=arr[low];
    return
}

除此之外,最小值/最大值可以更容易地计算:

mid=(low+high)/2;
halfarrsol(arr, low, mid, mi, ma); // get min/max
int minr, maxr;
halfarrsol(arr, mid+1, high, minr, maxr); // get right min/max
if (mi>minr){ // correct min if needed
    mi = minr;
}
if (ma<maxr){ // correct max if needed
    ma=maxr;
}