Segmentation Fault段错误:递归整理数组正负元素为何无限递归?
问题描述
- 需求目标:将数组的负元素排列在左侧(L.H.S),正元素排列在右侧(R.H.S)
- 实现方式:采用递归算法
- 使用数据类型:封装在结构体中的数组,即Array ADT
- 遇到问题:运行时报错Segmentation Fault,推测是递归函数被无限调用导致,相关代码如下:
#include <stdio.h> #include <stdlib.h> struct Array { int a[10]; int len; }; void swap(int *a,int *b) { int temp; temp = *a; *a = *b; *b = temp; } void NegativeSort(struct Array *arr, int i, int j) { if(i < j) { if(arr-> a[i] > 0 && arr-> a[j] <= 0) { swap(&arr-> a[i], &arr-> a[j]); NegativeSort(arr, i++, j--); } else if(arr-> a[i] >= 0) NegativeSort(arr, i, j--); else NegativeSort(arr, i++, j); } } int main() { struct Array arr = {{-1,2,-3,4,-5,6,-7,8},8}; NegativeSort(&arr, 0, 7); printf("elements are : "); for(i = 0; i < arr.len - 1; i++) printf("%d", arr.a[i]); return 0; }
段错误根本原因
- 递归调用时错误使用了后置自增/自减运算符:
i++、j--属于后置运算,会先把变量的原始值传入递归函数,再对当前作用域的i、j做增减。这就导致每一层递归收到的i和j的值永远和上层相同,i < j的判断条件永远成立,递归会无限执行,最终栈内存溢出触发段错误。 - 附加语法问题:
main函数中的循环变量i没有提前声明,部分编译器会直接报错。
修复方案
把所有递归调用时的后置自增/自减改为直接传递增减后的值,同时修复main函数的语法问题:
#include <stdio.h> #include <stdlib.h> struct Array { int a[10]; int len; }; void swap(int *a,int *b) { int temp; temp = *a; *a = *b; *b = temp; } void NegativeSort(struct Array *arr, int i, int j) { if(i < j) { if(arr->a[i] > 0 && arr->a[j] <= 0) { swap(&arr->a[i], &arr->a[j]); // 改为直接传递+1/-1后的值,不用后置运算 NegativeSort(arr, i+1, j-1); } else if(arr->a[i] >= 0) NegativeSort(arr, i, j-1); else NegativeSort(arr, i+1, j); } } int main() { struct Array arr = {{-1,2,-3,4,-5,6,-7,8},8}; NegativeSort(&arr, 0, 7); printf("elements are : "); // 声明循环变量i,同时修正循环边界、输出加空格便于阅读 for(int i = 0; i < arr.len; i++) printf("%d ", arr.a[i]); return 0; }
修复后运行输出示例:elements are : -1 -7 -3 -5 4 6 2 8 ,符合负元素在左、正元素在右的需求。
内容的提问来源于stack exchange,提问作者nSack
相关产品推荐
相关产品推荐

