C++程序for循环中途停止运行崩溃 求助问题定位
USACO练习代码二层循环处崩溃原因定位
根本原因
程序崩溃是数组下标越界访问非法内存导致的。
代码在判断#格子的相邻位置时,没有先判断相邻坐标是否在网格合法范围内,直接访问了不存在的内存位置:
- 遍历到第一行(
i=0)时,访问values[i-1][j]等价于访问values[-1][j],属于数组起始位置前的非法内存,之前没崩溃属于内存访问的巧合 - 遍历到最后一行(
i=R-1,测试用例里R=5,最后一行i=4)时,访问values[i+1][j]等价于访问values[5][j],超出vector存储的行范围 - 遍历到第一列(
j=0)时,访问values[i][j-1]等价于访问values[i][-1],属于行内列索引越界 - 遍历到最后一列(
j=C-1)时,访问values[i][j+1]等价于访问values[i][C],超出单行的字符存储范围
本次运行刚好在i=4,j=1位置碰到#字符,进入判断逻辑后访问的越界位置values[5][1]触发了系统内存访问保护,程序直接终止,和观测到的输出停止位置完全吻合。
修复方案
访问四个方向的相邻格子前,先判断对应坐标是否在0<=行号<R、0<=列号<C的合法范围内,仅当坐标合法时再读取对应位置的值,替换原有判断逻辑即可:
if(values[i][j] == '#') { bool existAdjacentA = false; // 检查上方相邻格 if (i - 1 >= 0 && values[i-1][j] == 'a') existAdjacentA = true; // 检查下方相邻格 if (i + 1 < R && values[i+1][j] == 'a') existAdjacentA = true; // 检查左侧相邻格 if (j - 1 >= 0 && values[i][j-1] == 'a') existAdjacentA = true; // 检查右侧相邻格 if (j + 1 < C && values[i][j+1] == 'a') existAdjacentA = true; if (!existAdjacentA) { values[i][j] = 'a'; counter += 1; } }
内容的提问来源于stack exchange,提问作者Jackie Wei
相关产品推荐
相关产品推荐

