C语言递归实现数组相邻元素交换遇长数组栈粉碎报错求解
问题原因
- 直接原因是数组下标越界写入触发栈溢出检测:
初始调用swap函数时传入的是数组总长度n(如长度为6时传入6),当递归返回到最顶层调用(len = n)时,len不等于arr_len - 1,且满足len > 1的条件,len会自增为n+1,后续交换a[len]和a[len-1]时访问了超出数组边界的内存,破坏了栈上的保护字段,触发stack smashing detected报错。
长度为4时未崩溃属于未定义行为的侥幸表现,实际上当时已经发生了越界访问,只是刚好没有破坏栈的关键数据。 - 根本原因是递归逻辑设计错误:原有逻辑通过修改入参
len的方式调整交换位置,逻辑混乱且依赖全局变量,既容易出现越界问题,也无法正确处理长度大于4的数组,长度为6时输出的2 1 4 5 6 3就不符合两两交换的预期。
修复方案
重新设计递归逻辑,核心思路为每次交换当前数组的前两位元素,再递归处理从第三位开始的剩余子数组,无需修改入参、也不需要全局变量:
#include <stdio.h> void swap(int *a, int len) { // 剩余元素不足2个,无需交换直接返回 if (len < 2) return; // 交换当前段前两个元素 int tmp = a[0]; a[0] = a[1]; a[1] = tmp; // 递归处理后面的剩余元素,指针后移2位,长度减2 swap(a + 2, len - 2); } int main() { int a[] = {1,2,3,4,5,6}, i; int arr_len = sizeof(a)/sizeof(a[0]); swap(a, arr_len); for (i = 0; i < arr_len; i++) printf("%d\n", a[i]); return 0; }
修复后对于长度为6的数组输出为:
2 1 4 3 6 5
符合预期,且不存在越界访问问题。
内容的提问来源于stack exchange,提问作者Milan
相关产品推荐
相关产品推荐

