C++ 2D Vector赋值后显示异常,同逻辑2D Array正常
C++二维Vector数据异常问题排查
问题现象
- 从一维
vector<int>复制数据到二维vector<vector<double>>时,循环内部输出数据完全正确,但循环结束后部分位置数据异常(如[0][6]、[0][7]、[1][6]、[1][7]),最后一行始终正常;修改nSets参数后,前几行末尾2个位置仍会损坏。 - 相同复制逻辑下,固定大小的二维数组
int nArray[3][8]所有数据输出均正常。
复现代码
#include <iostream> #include <vector> using namespace std; int nCol = 8; int nSize = 4; int nLookBack = 2; int nSets = 3; int nInputs = 4; int nArray[3][8]; int main() { // 创建数据集 vector<int> nData(80); for(int i = 0; i < 80; i++) { nData[i] = i+1; } // 展示原始数据 for(int i = 0 ; i < 80; i+=nCol) { for(int j = 0; j < nCol; j++) { cout << nData[i+j] << "\t"; } cout << endl; } cout << endl << endl; // +----------------------------------------------------- vector<vector<double>> nVector( nSets , vector<double> (nInputs)); // 从nVector复制数据到2D vector和2D array cout << "循环内部输出:" << endl; for(int i = 0; i < nSets ; i++) { for(int j = 0; j< nLookBack ; j++) { // 复制数据到2D vector nVector[i] [(j * nSize ) + 0 ] = nData[ ((i+j) * nCol) + 0] ; nVector[i] [(j * nSize ) + 1 ] = nData[ ((i+j) * nCol) + 1] ; nVector[i] [(j * nSize ) + 2 ] = nData[ ((i+j) * nCol) + 2] ; nVector[i] [(j * nSize ) + 3 ] = nData[ ((i+j) * nCol) + 3] ; // 循环内展示2D vector数据 cout << "[" << i << "][" << (j * nSize ) + 0 << "] = " << nVector[i] [(j * nSize ) + 0 ] << "\t" ; cout << "[" << i << "][" << (j * nSize ) + 1 << "] = " << nVector[i] [(j * nSize ) + 1 ] << "\t" ; cout << "[" << i << "][" << (j * nSize ) + 2 << "] = " << nVector[i] [(j * nSize ) + 2 ] << "\t" ; cout << "[" << i << "][" << (j * nSize ) + 3 << "] = " << nVector[i] [(j * nSize ) + 3 ] << "\t" ; // 复制数据到2D array nArray[i] [(j * nSize ) + 0 ] = nData[ ((i+j) * nCol) + 0] ; nArray[i] [(j * nSize ) + 1 ] = nData[ ((i+j) * nCol) + 1] ; nArray[i] [(j * nSize ) + 2 ] = nData[ ((i+j) * nCol) + 2] ; nArray[i] [(j * nSize ) + 3 ] = nData[ ((i+j) * nCol) + 3] ; } cout << endl; } // +----------------------------------------------------- // 展示2D vector数据 cout << endl << "二维vector输出:" << endl; for(int i = 0; i < nSets ; i++) { for(int j = 0; j < (nLookBack * nSize); j++) { cout << " [" << i << "][" << j << "] = " << nVector[i][j] << "\t" ; } cout << endl; } // +----------------------------------------------------- // 展示2D array数据 cout << endl << "二维数组输出:" << endl; for(int i = 0; i < nSets ; i++) { for(int j = 0; j < (nLookBack * nSize); j++) { cout << " [" << i << "][" << j << "] = " << nArray[i][j] << "\t" ; } cout << endl; } return 0; }
输出对比
循环内部输出
[0][0] = 1 [0][1] = 2 [0][2] = 3 [0][3] = 4 [0][4] = 9 [0][5] = 10 [0][6] = 11 [0][7] = 12 [1][0] = 9 [1][1] = 10 [1][2] = 11 [1][3] = 12 [1][4] = 17 [1][5] = 18 [1][6] = 19 [1][7] = 20 [2][0] = 17 [2][1] = 18 [2][2] = 19 [2][3] = 20 [2][4] = 25 [2][5] = 26 [2][6] = 27 [2][7] = 28
二维Vector输出
[0][0] = 1 [0][1] = 2 [0][2] = 3 [0][3] = 4 [0][4] = 9 [0][5] = 10 [0][6] = 9 [0][7] = 10 [1][0] = 9 [1][1] = 10 [1][2] = 11 [1][3] = 12 [1][4] = 17 [1][5] = 18 [1][6] = 17 [1][7] = 18 [2][0] = 17 [2][1] = 18 [2][2] = 19 [2][3] = 20 [2][4] = 25 [2][5] = 26 [2][6] = 27 [2][7] = 28
二维数组输出
[0][0] = 1 [0][1] = 2 [0][2] = 3 [0][3] = 4 [0][4] = 9 [0][5] = 10 [0][6] = 11 [0][7] = 12 [1][0] = 9 [1][1] = 10 [1][2] = 11 [1][3] = 12 [1][4] = 17 [1][5] = 18 [1][6] = 19 [1][7] = 20 [2][0] = 17 [2][1] = 18 [2][2] = 19 [2][3] = 20 [2][4] = 25 [2][5] = 26 [2][6] = 27 [2][7] = 28
问题原因
核心问题是二维Vector的初始化大小错误:
- 代码中初始化二维Vector时,每个子Vector的大小被设置为
nInputs=4,但实际需要存储的列数是nLookBack * nSize = 2*4=8。 - 后续访问索引4-7的位置属于数组越界访问,这是C++中的未定义行为——写入越界位置会覆盖相邻内存区域的数据,循环内部刚写入时内存未被改写所以输出正常,但后续操作会破坏这些越界存储的数据,导致最终读取异常。
- 二维数组是固定大小8列,不存在越界问题,因此数据始终正确。
解决方法
修改二维Vector的初始化代码,将子Vector的大小设置为实际需要的列数nLookBack * nSize:
// 计算实际需要的列数 int requiredCols = nLookBack * nSize; vector<vector<double>> nVector(nSets, vector<double>(requiredCols));
或者直接在初始化时计算:
vector<vector<double>> nVector(nSets, vector<double>(nLookBack * nSize));
内容的提问来源于stack exchange,提问作者Osiris
相关产品推荐
相关产品推荐

