为何C++ vector直接访问触发越界错误,而for循环可正常运行?
vector访问越界异常问题分析
代码片段
#include <iostream> #include <string> #include <vector> using std::cin; using std::cout; using std::endl; using std::string; using std::vector; int main() { int n, x, y, z, xres, yres, zres; cin >> n; vector<vector<int>> vec(n); while(n--) { vector<int> aux(3); cin >> aux.at(0) >> aux.at(1) >> aux.at(2); vec.push_back(aux); } for ( int i = 0; i < vec.size(); i++ ) { for (int j = 0; j < vec[i].size(); j++) { cout << vec.at(i).at(j) << " "; } cout << endl; } cout << vec.at(0).at(0); return 0; }
输入数据
3 1 2 3 1 2 3 1 2 3
报错信息
terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check: __n (which is 0) >= this->size() (which is 0) Aborted (core dumped)
问题原因
你遇到的矛盾现象本质是vector的结构被错误初始化导致的:
- 初始化语句
vector<vector<int>> vec(n);会直接创建n个空的vector对象 ,此时vec的总长度是n,前n个位置都是空容器。 - 后续
while(n--)循环执行n次,每次用push_back往vec末尾添加一个带数据的vector,最终vec的总长度变成2n。前n个元素是空容器,后n个才是你输入的有效数据。 - 遍历输出时,前n个空容器的
size()为0,内层循环不会执行,只会输出换行;后n个有效容器正常输出数据,所以你误以为遍历“正常”,但实际上前半部分都是空的。 - 最后访问
vec.at(0).at(0)时,vec[0]是初始化时的空vector,调用at(0)访问它的第一个元素,自然触发越界异常——这个子容器的长度是0,根本没有元素。
修复方案
有两种简单的修复方式:
- 方式一:取消预初始化
把vector初始化语句改成空容器,直接通过push_back添加元素:vector<vector<int>> vec; // 不再预分配n个空元素 - 方式二:用下标赋值代替push_back
保留预初始化,但循环时直接给已有的空容器赋值,而不是添加新元素:// 把while循环改成for循环,避免n被修改后影响下标 for (int i = 0; i < n; ++i) { vector<int> aux(3); cin >> aux[0] >> aux[1] >> aux[2]; vec[i] = aux; // 给预初始化的第i个容器赋值 }
内容的提问来源于stack exchange,提问作者bugwriter123
相关产品推荐
相关产品推荐

