C语言递归冒泡排序处理大数据时触发Segmentation fault问题求助
问题根源:递归栈溢出
你遇到的Segmentation Fault是递归调用栈溢出导致的。递归版冒泡排序的递归深度等于数组长度:当你设置num=40000时,recur_BubbleSort会被连续调用40000次,每次调用都会在进程的栈空间中创建一个栈帧(保存返回地址、函数参数等数据)。而系统默认给进程分配的栈空间通常只有几MB,40000个栈帧的总大小会超出栈的容量,直接触发栈溢出错误。这就是为什么num低于35000时正常,超过后崩溃的原因——35000是你的系统栈能容纳的最大递归层数阈值。
解决方案
1. 替换为迭代版冒泡排序(最推荐)
彻底消除递归依赖,完全避免栈溢出问题,同时迭代版的效率也略高于递归版。修改排序函数为:
void swap(int *arr, int i, int j) { int temp_num = arr[i]; arr[i] = arr[j]; arr[j] = temp_num; } void iter_BubbleSort(int *arr, int len) { // 外层循环控制排序轮数 for (int i = 0; i < len - 1; i++) { // 内层循环进行相邻元素比较交换,每轮减少i次比较(末尾已排好序) for (int j = 0; j < len - 1 - i; j++) { if (arr[j] > arr[j + 1]) { swap(arr, j, j + 1); } } } }
然后在主函数中替换调用:
// 替换原来的recur_BubbleSort调用 iter_BubbleSort(data_int, num);
2. (可选)调整系统栈大小(不推荐)
如果必须保留递归版本,可以尝试增大进程的栈空间,但这种方法依赖操作系统和编译器,移植性很差:
- Linux/macOS:运行程序前执行
ulimit -s 16384(设置栈大小为16MB) - Windows(MSVC):编译时添加链接选项
-Wl,--stack,16777216(设置栈大小为16MB)
3. 尾递归优化(效果不可靠)
部分编译器(如GCC)会将尾递归优化为循环,但冒泡排序的递归结构很难改成标准的尾递归形式,因此不建议依赖这种方式解决问题。
额外代码优化建议
你的主函数中feof的用法存在逻辑瑕疵,正确的文件读取循环应该把fgets作为循环条件,同时避免重复调用atoi:
// 替换原有的读取循环 while (line < num && fgets(data, MAX, fpt) != NULL) { data_int[line] = atoi(data); if (num <= 100) { printf("[%d]\n", data_int[line]); } line++; }
内容的提问来源于stack exchange,提问作者Cris
相关产品推荐
相关产品推荐

