C语言找数组最小值代码报stack smashing detected排查
*** stack smashing detected ***: terminated 报错原因 这个报错是编译器内置的栈保护机制触发的终止逻辑:当代码出现栈内存越界写入,覆盖了编译器预先插入在栈帧中的校验值(Stack Canary)时,程序会判定内存被非法篡改,主动终止运行,避免出现安全漏洞。
你代码中存在的具体问题
- 数组长度计算错误,直接导致越界访问
你定义的arr是包含20个int元素的数组,sizeof(arr)返回的是数组占用的总内存字节数(32/64位环境下int占4字节,总大小为80字节),不是数组的元素个数20。你写的第二层循环for(i=0;i<sizeof(arr)-1;i++)会遍历到下标78,访问arr[i+1]时会读写数组合法范围(下标0~19)之外的栈内存,直接触发栈保护报错。哪怕你输入的数组长度num远小于20,这个循环依然会访问到数组未初始化的越界区域,读到随机垃圾值的同时篡改栈内存。 - 最小值查找逻辑错误
你写的相邻交换逻辑是单轮冒泡排序的片段,只会把数组中的最大值移动到遍历范围的末尾,无法将最小值移动到数组首位置,就算修正了数组长度计算问题,最终输出的arr[0]也不是正确的最小值。 - 缺少输入合法性校验
第一个读入数组的循环没有判断输入的num是否超过数组容量20,如果输入的num大于20,读入环节就会发生数组越界写入,同样会触发栈粉碎报错。
修正后的参考实现
找最小值不需要修改原数组,只需要遍历一次记录最小值即可,时间复杂度更低:
#include<stdio.h> int main(){ int arr[20], i, min, num; scanf("%d", &num); // 校验输入长度合法性 if (num < 1 || num > 20) { printf("输入数组长度非法,需在1~20范围内"); return 1; } for (i = 0; i < num; i++) { scanf("%d", &arr[i]); } // 遍历找最小值 min = arr[0]; for (i = 1; i < num; i++) { if (arr[i] < min) { min = arr[i]; } } printf("%d", min); return 0; }
如果坚持用排序后取首元素的方式实现,要注意两点:一是循环边界必须基于实际输入的元素个数
num计算,不能直接用sizeof(arr);二是单轮相邻交换无法完成排序,需要写完整的多层排序循环逻辑。
内容的提问来源于stack exchange,提问作者Nitin Pandey
相关产品推荐
相关产品推荐

