C++如何向仅reserve内存的vector<vector<Object>>二维向量push_back元素
C++ 二维稀疏vector的push_back实现方案
原有预分配代码的问题
你现在写的预分配逻辑存在未定义行为:_meshMatrix.reserve(_numRefElementsPerRow)仅为外层vector预留了足够的内存空间,但此时外层vector的实际元素个数size()仍为0,直接通过_meshMatrix[i]访问下标属于越界访问,会直接触发程序崩溃。
另外你原有赋值逻辑的内层循环存在笔误,判断条件误写为column < _numRefElementsPerRow,应该为列数_numRefElementsPerColumn。
场景1:所有行都存在,仅每行内元素稀疏
如果所有行都需要保留,只是每行不需要填满_numRefElementsPerColumn个元素,按如下方式修改:
修正后的预分配逻辑
// 先构造出所有行的空内层vector,此时外层size等于行数 _meshMatrix.resize(_numRefElementsPerRow); for(unsigned int i = 0; i < _numRefElementsPerRow ; i++) // 为每个行的内层vector预留列数空间,避免后续push_back频繁扩容 _meshMatrix[i].reserve(_numRefElementsPerColumn);
插入逻辑
判断当前位置需要填充时,给对应行的vector执行push_back即可:
for(unsigned int row = 0; row < _numRefElementsPerRow; row++) { for(unsigned int column = 0; column < _numRefElementsPerColumn; column++) { if (/* 自定义:当前(row, column)需要填充的判断条件 */) { // 如果需要保留列位置信息,建议内层vector改为vector<pair<unsigned int, Foo>>,用下面的写法 // _meshMatrix[row].emplace_back(column, someFooObject); // 不需要保留位置信息直接用普通push_back _meshMatrix[row].push_back(someFooObject); } } }
场景2:连行都是稀疏的,部分行完全无元素
如果大量行完全不需要填充,可以连行也省略,进一步节省内存:
预分配逻辑
仅需要给外层vector预留空间即可:
_meshMatrix.reserve(_numRefElementsPerRow);
插入逻辑
按行遍历,仅当行内存在需要填充的元素时,才把行插入外层vector:
for(unsigned int row = 0; row < _numRefElementsPerRow; row++) { vector<Foo> currentRow; currentRow.reserve(_numRefElementsPerColumn); for(unsigned int column = 0; column < _numRefElementsPerColumn; column++) { if (/* 自定义:当前(row, column)需要填充的判断条件 */) { // 同样需要保留位置的话存pair currentRow.emplace_back(column, someFooObject); // 不需要的话直接push_back(someFooObject) } } // 仅当前行有元素时才插入外层vector if (!currentRow.empty()) { // 用移动语义避免拷贝开销 _meshMatrix.push_back(std::move(currentRow)); // 如果需要保留行号,可额外维护一个行号到外层下标的映射表 } }
额外优化建议
如果你的矩阵稀疏度非常高(有效元素占比低于10%),可以考虑改用压缩稀疏行(CSR)、坐标存储(COO)等专用稀疏矩阵结构,内存利用率会更高。
内容的提问来源于stack exchange,提问作者some_math_guy
相关产品推荐
相关产品推荐

