解决老鼠走迷宫问题时触发SIGABRT信号,请求排查原因
问题排查:老鼠走迷宫代码触发SIGABRT信号
问题描述
在实现老鼠走迷宫问题时,代码中标记的行在str为"DDRDRR"时触发SIGABRT信号,程序无法正常运行。
代码中的核心问题
1. 函数缺少返回值
check函数声明返回vector<string>,但仅在到达终点时返回了soln,其余分支没有返回语句。这会导致未定义行为,程序可能直接崩溃(比如触发SIGABRT)。
2. 错误使用else if导致路径无法回溯
当前代码用else if串联四个方向的判断,意味着每次递归只能尝试一个方向,无法回溯去尝试其他可能的路径,同时会丢失大量有效路径。
3. 值传递导致结果无法累积
soln参数是值传递,递归中添加的路径不会传递回上层函数,最终无法收集到所有有效路径。
4. 原矩阵被修改且未恢复
代码中将m[i][j]设为0标记已访问,但递归返回后没有恢复为1,导致后续路径无法正确访问该位置,逻辑出现混乱。
修正后的代码
#include <bits/stdc++.h> using namespace std; class Solution{ public: // 改为引用传递soln,避免值拷贝丢失结果 void check(int i, int j, vector<vector<int>> &m, string str, vector<string> &soln, int n) { if(i == n-1 && j == n-1) { soln.push_back(str); return; } // 标记当前位置已访问 m[i][j] = 0; // 四个方向用独立if,允许回溯尝试多个方向 // 向下 if(i+1 <= n-1 && m[i+1][j] == 1) { check(i+1, j, m, str + "D", soln, n); } // 向右 if(j+1 <= n-1 && m[i][j+1] == 1) { check(i, j+1, m, str + "R", soln, n); } // 向上 if(i-1 >= 0 && m[i-1][j] == 1) { check(i-1, j, m, str + "U", soln, n); } // 向左 if(j-1 >= 0 && m[i][j-1] == 1) { check(i, j-1, m, str + "L", soln, n); } // 回溯:恢复当前位置为可访问 m[i][j] = 1; } vector<string> findPath(vector<vector<int>> &m, int n) { vector<string> soln; if(m[0][0] == 0 || m[n-1][n-1] == 0) { return soln; } // 复制原矩阵,避免修改输入的原始矩阵 vector<vector<int>> maze = m; check(0, 0, maze, "", soln, n); sort(soln.begin(), soln.end()); return soln.empty() ? vector<string>{ "-1" } : soln; } }; int main() { int t; t = 1; while (t--) { int n = 4; vector<vector<int>> m{{1, 0, 0, 0}, {1, 1, 0, 1}, {1, 1, 0, 0}, {0, 1, 1, 1}}; Solution obj; vector<string> result = obj.findPath(m, n); for(const string &path : result) { cout << path << " "; } cout << endl; } return 0; }
修正说明
- 修复返回值问题:将
check改为无返回值函数,通过引用传递soln收集结果,彻底避免无返回值的未定义行为。 - 完善回溯机制:每次递归返回后恢复当前位置的矩阵值为1,确保其他路径可正常访问;通过
str + "D"的方式传递字符串,自然实现字符串的回溯,无需额外修改。 - 调整方向判断逻辑:用独立
if替代else if,允许递归尝试所有可行方向,不会错过有效路径。 - 保护原输入:复制原矩阵到临时变量中操作,避免修改用户传入的原始数据。
内容的提问来源于stack exchange,提问作者Shubham
相关产品推荐
相关产品推荐

