二维vector需先分配空间再访问,如vector<vector<int>> v(3, vector<int>(4));初始化用{{1,2},{3,4}};访问应使用at()或手动检查边界,避免越界未定义行为。

vector> 是最常用写法,但别直接 push_back 一个空 vector
定义二维 vector 最常见的是 vector<vector>></vector>,它本质是「vector 里存着一堆 vector」。但新手常误以为声明完就能直接用下标赋值,比如:v[0][0] = 1——这会崩溃,因为外层 vector 还没任何元素,v[0] 根本不存在。
正确做法是先确保外层有足够多的子 vector:
- 用构造函数一次性分配好行数:
vector<vector>> v(3, vector<int>(4));</int></vector>→ 3 行 4 列,所有元素初始化为 0 - 或逐行 push:
v.push_back(vector<int>(4));</int>,再对v[i]做操作 - 若不确定尺寸,务必先
v.resize(n)或检查v.size() > i再访问v[i]
初始化时用大括号嵌套容易出错:{} 和 {{}} 含义完全不同
用初始化列表写二维 vector 时,{} 层级很关键。例如:vector<vector>> v = {{1,2}, {3,4}};</vector> 是合法的;但 vector<vector>> v = {1,2,3,4};</vector> 编译失败——编译器试图把整数转成 vector<int></int>,类型不匹配。
更隐蔽的问题是混用指针或临时对象:
立即学习“C++免费学习笔记(深入)”;
- 错误:
vector<vector>> v = {{1,2}, vector<int>{3,4}};</int></vector>→ 可能触发不必要的拷贝(C++17 后通常优化掉,但旧标准风险高) - 推荐统一风格:
vector<vector>> v = {{1,2}, {3,4}};</vector>,所有子 vector 都用花括号字面量 - 如果子 vector 长度不一(不规则数组),必须显式写出每行:
{{1}, {2,3}, {4,5,6}},不能靠 resize 补零
访问越界不会报错,但运行时行为未定义
vector 的 operator[] 不做边界检查,v[100][100] 在未分配空间时看似“能跑”,实则踩内存,后续可能 crash、数据错乱或静默失败。
安全做法只有两种:
- 用
at()替代[]:v.at(i).at(j) = x;,越界抛std::out_of_range - 手动检查:
if (i - 注意:
v[i].size()可能为 0(某行为空),此时v[i][0]一定非法
性能敏感场景慎用 vector>,内存不连续
每个内层 vector 单独在堆上分配,导致行与行之间地址不连续。CPU 缓存预取失效,遍历效率比一维数组低不少,尤其在数值计算中明显。
替代方案取决于需求:
- 固定尺寸且追求速度:用一维
vector<t></t>模拟二维,索引算作v[i * cols + j] - 需要动态增删行:仍可用
vector<vector>></vector>,但避免频繁插入中间行(O(n) 移动指针) - 需要随机访问+高效列操作:考虑
vector+ 自定义 view,或用boost::multi_array等专用库
真正麻烦的是混合操作:既要快速按行追加,又要频繁按列求和——这时候二维 vector 的结构就暴露短板了,得重新权衡设计。










