C++用二维数组实现乘法表时触发Stack Smashing错误的原因排查
Stack Smashing错误的触发原因
本质是栈内存越界写入,数组索引超出了定义的合法访问范围
- C++的数组索引从0开始计数,你定义的
int timesTable[10][10],合法的行、列索引范围均为0~9,不存在索引值为10的数组元素。 - 你的循环设计中,i、j的取值范围是1到10(对应循环条件
i < 11、j < 11),当i=10、j=10时,执行timesTable[i][j] = i * j的写入操作,已经越过了整个二维数组的内存边界,将数据写入到栈上不属于该数组的相邻内存区域。 - 为什么程序能正常完成乘法表打印?因为越界写入的这块临时内存,在当前程序执行流程中没有被其他关键逻辑占用,不会干扰乘法表的计算和输出过程。但当程序执行到
return 0准备退出main函数时,编译器默认开启的栈保护校验逻辑会检测到栈帧的关键元数据(比如栈校验Cookie、函数返回地址)被意外改写,随即触发Stack Smashing的运行时报错。
可行的修正方案
两种适配思路可以选择:
- 保留原有10*10的数组尺寸,调整循环逻辑匹配C++的0起始索引规则:
- 将循环的取值范围修改为i、j从0到9,对应循环条件写为
i < 10、j < 10 - 乘法计算逻辑对应调整为
timesTable[i][j] = (i + 1) * (j + 1),保证最终打印的仍然是1~10的标准乘法表内容
- 将循环的取值范围修改为i、j从0到9,对应循环条件写为
- 匹配原有1到10的循环索引,将数组尺寸扩展为11*11,让索引10落在合法访问范围内。这种方式会浪费第0行、第0列的内存空间,不推荐优先使用。
内容的提问来源于stack exchange,提问作者Ken
相关产品推荐
相关产品推荐

