提问人:user22021739 提问时间:6/12/2023 更新时间:6/12/2023 访问量:56
在递归函数中使用按引用调用返回多个值时出现分段错误
Getting segmentation fault while using call by reference to return multiple values in recursive function
问:
问题是在数组中找到最大和最小元素并返回它们的差值。我提到了 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 个值。
有没有办法使用引用调用递归地解决这个问题?
如果需要,您可以在此处查看驱动程序代码
答:
如果你专注于逻辑,这个错误就不容易弄清楚。你的逻辑或多或少是正确的,问题是当 时,它将无限期地递归调用函数,因为你没有返回你没有使用过的函数。更改为以下内容:low == high
else if
high == 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 {
...
评论
else if
递归永不停止。在第一种情况下,您忘记结束它:
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;
}
下一个:指针值差异不符合预期
评论
mid
max
min