C++使用std::vector初始化矩阵时触发std::bad_alloc错误求助
问题分析与修复方案
嘿,你的代码触发std::bad_alloc的核心问题其实是迭代器失效了,咱们来拆解一下:
当你对A调用A.push_back(std::vector<double> {});的时候,如果vector当前的内存空间不够容纳新元素,它会重新分配一块更大的内存区域,把原来的元素全部移过去,然后释放旧内存。这时候你之前保存的迭代器it就变成了“野指针”——指向的是已经被系统回收的旧内存,后续再用it++和it->push_back()操作,就会触发未定义行为,表现出来就是内存分配错误(bad_alloc)。
几种修复方式
方式1:放弃旧迭代器,重新获取指向新行的迭代器
每次push_back之后,别再用之前的迭代器了,直接获取新行的迭代器:
#include <iostream> #include <vector> void print(std::vector<std::vector<double>> matrix) { typedef std::vector<std::vector<double>> row; typedef std::vector<double> col; for(row::iterator it = matrix.begin();it!=matrix.end();it++) { for(col::iterator ti = it->begin();ti!=it->end();ti++) { std::cout << *ti << ' '; } std::cout << '\n'; } } int main() { std::vector<std::vector<double>> A {std::vector<double> {}}; auto it = A.begin(); it->push_back(1); it->push_back(2); it->push_back(3); A.push_back(std::vector<double> {}); // 直接拿到最后一行的迭代器,不用旧的it++ it = A.end() - 1; it->push_back(4); it->push_back(5); it->push_back(6); print(A); return 0; }
方式2:提前预留空间,避免内存重分配
如果你提前知道矩阵需要多少行,可以用reserve预留足够的内存,这样push_back不会触发内存重分配,迭代器就不会失效:
int main() { std::vector<std::vector<double>> A; // 提前预留2行的空间,后续push_back不会触发内存重分配 A.reserve(2); A.push_back(std::vector<double> {}); auto it = A.begin(); it->push_back(1); it->push_back(2); it->push_back(3); A.push_back(std::vector<double> {}); it++; // 此时迭代器依然有效 it->push_back(4); it->push_back(5); it->push_back(6); print(A); return 0; }
方式3:直接用下标访问,简单又省心
其实对于嵌套vector来说,直接用[]下标访问行比迭代器更直观,完全不用担心迭代器失效的问题:
int main() { std::vector<std::vector<double>> A(2); // 直接初始化2行空向量 A[0].push_back(1); A[0].push_back(2); A[0].push_back(3); A[1].push_back(4); A[1].push_back(5); A[1].push_back(6); print(A); return 0; }
小提醒:vector迭代器失效规则
以后用vector迭代器的时候要注意这些情况:
- 当
push_back、insert等操作导致内存重新分配时,所有迭代器、指针、引用都会失效 - 如果没触发内存重分配(比如提前
reserve了),只有插入点之后的迭代器失效 erase操作会导致被删除元素及其之后的迭代器失效
内容的提问来源于stack exchange,提问作者Nagesh Eranki
相关产品推荐
相关产品推荐

