关于std::out_of_range报错含义及二维向量相邻值分组异常的咨询
一、关于
terminate called after throwing an instance of 'std::out_of_range'的含义 这个错误表示程序触发了std::out_of_range异常,但没有代码捕获处理该异常,最终导致程序强制终止。
- 最常见诱因是使用
std::vector的at()方法访问了超出容器有效索引范围的位置:at()会严格校验索引合法性,一旦索引小于0或大于等于容器大小,就会抛出该异常;若用[]运算符访问越界索引,不会触发异常,但会引发未定义行为(如程序崩溃、数据乱码)。
二、代码问题的修复方案
你的代码存在两个核心问题,导致程序提前终止且功能不符合预期:
1. 越界访问触发异常
在groupFind函数中,你先判断元素值是否为1,再检查边界,这会直接导致越界访问:
比如当x是最后一行索引时,x+1会超出二维vector的行范围,此时调用table.at(x+1).at(y)会触发std::out_of_range异常,直接导致程序崩溃。
修复方式:交换判断顺序,先检查边界,再访问元素(利用逻辑与的短路特性,边界不合法时不会执行后续的元素访问):
if(in_bound(x+1, y) && table.at(x+1).at(y) == 1) groupFind(table, x+1, y); if(in_bound(x-1, y) && table.at(x-1).at(y) == 1) groupFind(table, x-1, y); if(in_bound(x, y+1) && table.at(x).at(y+1) == 1) groupFind(table, x, y+1); if(in_bound(x, y-1) && table.at(x).at(y-1) == 1) groupFind(table, x, y-1);
2. 传值导致无法标记已访问元素
groupFind函数的参数vector<vector<int>> table是传值方式,每次调用都会创建table的副本,你在副本中把元素设为2的操作不会影响原table。这会导致同一个元素被反复处理,甚至陷入无限递归,同时分组结果也会出错。
修复方式:把参数改成传引用,这样修改的是原table的内容:
void groupFind(vector<vector<int>>& table, int x, int y){ table.at(x).at(y) = 2; temp.push_back(make_pair(x, y)); // 修复后的边界判断+元素检查 if(in_bound(x+1, y) && table.at(x+1).at(y) == 1) groupFind(table, x+1, y); if(in_bound(x-1, y) && table.at(x-1).at(y) == 1) groupFind(table, x-1, y); if(in_bound(x, y+1) && table.at(x).at(y+1) == 1) groupFind(table, x, y+1); if(in_bound(x, y-1) && table.at(x).at(y-1) == 1) groupFind(table, x, y-1); }
额外优化建议
避免使用全局变量temp,可以把它作为引用参数传入groupFind函数,增强代码可读性和可维护性:
void groupFind(vector<vector<int>>& table, int x, int y, vector<pair<int, int>>& temp){ table.at(x).at(y) = 2; temp.push_back(make_pair(x, y)); if(in_bound(x+1, y) && table.at(x+1).at(y) == 1) groupFind(table, x+1, y, temp); if(in_bound(x-1, y) && table.at(x-1).at(y) == 1) groupFind(table, x-1, y, temp); if(in_bound(x, y+1) && table.at(x).at(y+1) == 1) groupFind(table, x, y+1, temp); if(in_bound(x, y-1) && table.at(x).at(y-1) == 1) groupFind(table, x, y-1, temp); }
调用时修改为:
if(table.at(i).at(j) == 1){ vector<pair<int, int>> temp; groupFind(table, i, j, temp); grupet.push_back(temp); }
内容的提问来源于stack exchange,提问作者greasypan
相关产品推荐
相关产品推荐

