*** stack smashing detected ***错误成因与解决方法(C++数组场景)
C++众数查找函数栈溢出错误的成因与解决
问题背景
编写了一个C++函数,接收长度为100、元素为0-25整数(存储为double类型)的升序排序数组,用于查找并返回众数,同时打印直方图辅助可视化。函数有时正常运行,但偶尔会触发*** stack smashing detected ***错误(使用Replit作为IDE)。
函数代码如下:
double mode(double * n){int x=0,r=0,R=0; for(int i=1;i!=100;i++){ if(n[i]==n[i-1])r++; else { if(r>R){ R=r; x=n[i-1];} cout<<n[i-1]<<" "; for(int L=0;L!=r;L++)cout<<"*"; r=0; cout<<endl;}} return x;}
调试时未触发错误,但错误发生时输出会随机出现极大/极小的科学计数法数值,示例:
0 ** 5.22851e-33 <--this guy here is what im talking about 1 2 * 3 ****** 4 * 5 ***** 6 *** 7 ***** 8 ***** 9 ** 10 *** 11 *** 12 ***** 13 ***** 14 ** 15 ** 16 *** 17 *** 18 * 19 **** 20 ** 21 *** 22 ** 23 **** 24 *** stack smashing detected ***: terminated signal: aborted (core dumped)
错误成因
- 数组越界访问:循环条件
i!=100会让i最终走到100,此时n[i]访问的是数组第101个元素(C++数组索引从0开始,长度100的数组有效索引为0-99)。越界访问会破坏栈上的保护数据或其他变量,触发栈溢出检测。 - 未处理最后一组元素:循环结束后,数组最后一组连续相同的元素未被统计和打印,此时栈数据可能因之前的越界操作被篡改,导致输出随机无效值。
解决方法
修改函数,修复越界问题并处理最后一组元素,代码如下:
#include <iostream> using namespace std; double mode(double *n) { int count = 1, max_count = 1; double current_mode = n[0]; for (int i = 1; i < 100; ++i) { if (n[i] == n[i-1]) { ++count; } else { // 更新众数 if (count > max_count) { max_count = count; current_mode = n[i-1]; } // 打印当前组直方图 cout << n[i-1] << " "; for (int j = 0; j < count; ++j) { cout << "*"; } cout << endl; count = 1; } } // 处理最后一组元素 if (count > max_count) { max_count = count; current_mode = n[99]; } cout << n[99] << " "; for (int j = 0; j < count; ++j) { cout << "*"; } cout << endl; return current_mode; }
关键修改说明
- 循环条件改为
i < 100,确保仅访问数组有效索引范围内的元素,避免越界。 - 初始化计数为1(每个元素至少出现一次),原代码初始为0会导致统计次数少1。
- 循环结束后添加最后一组元素的处理逻辑,保证所有元素都被统计和打印。
- 初始化众数为数组第一个元素,避免所有元素相同时众数初始值错误。
内容的提问来源于stack exchange,提问作者CONNOR STERNE
相关产品推荐
相关产品推荐

