实现数组最大连续和的递归C函数出现segmentation fault的原因排查
问题分析与修复
错误原因
你遇到的0xC00000FD是栈溢出错误,根源是无限递归,同时代码还存在数组元素处理不全的逻辑错误:
- 无限递归触发栈溢出:函数第一行执行
n -= 1后,当递归调用传入n=0时,n会变成-1,无法触发终止条件if(n == 0),进而进入else分支继续递归,最终耗尽栈空间。 - 数组元素处理遗漏:递归调用时传递的参数是
n-1(此时n已被减过1),导致跳过了中间的数组元素,完全偏离了求最大连续和的逻辑。
修正后的代码
以下是符合递归逻辑的实现,核心思路是:每次递归处理数组的前n-1个元素,再结合当前元素更新全局最大和与最大后缀和:
#include <math.h> // 需要用到fmax函数 double rsubMax(double *x, double *sfm, int n) { // 终止条件:只剩一个元素时,最大后缀和与全局最大都是该元素 if (n == 1) { *sfm = x[0]; return x[0]; } // 递归处理前n-1个元素,拿到前n-1个的全局最大和最大后缀和 double globalMax = rsubMax(x, sfm, n - 1); // 计算当前的最大后缀和:要么是之前的后缀和加当前元素,要么从当前元素重新开始(之前后缀和为负时) *sfm = fmax(*sfm + x[n-1], x[n-1]); // 更新全局最大和:取之前的全局最大与当前后缀和的较大值 globalMax = fmax(globalMax, *sfm); return globalMax; }
代码说明
- 终止条件明确:当
n==1时,直接返回唯一的元素作为全局最大和后缀和。 - 递归逻辑清晰:每次递归处理前
n-1个元素,确保每个数组元素都被遍历到。 - 后缀和更新合理:如果之前的后缀和为负,加上当前元素会比当前元素本身更小,此时直接以当前元素作为新的后缀和起点。
调用示例
确保调用时传入有效的sfm指针(不能为NULL):
#include <stdio.h> int main() { double arr[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; int n = sizeof(arr) / sizeof(arr[0]); double sfm; double maxSum = rsubMax(arr, &sfm, n); printf("最大连续和:%.2lf\n", maxSum); // 输出6.00,对应子数组[4,-1,2,1] return 0; }
内容的提问来源于stack exchange,提问作者despinxz
相关产品推荐
相关产品推荐

