C++向量与矩阵乘积程序处理非方阵时崩溃的问题排查
问题:非方阵输入导致矩阵乘积程序崩溃
实现了一个支持向量点积、矩阵-向量积、矩阵乘积的程序,处理向量和方阵时正常,但输入非方阵时崩溃,抛出以下异常:
terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check: __n (which is 1) >= this->size() (which is 1)
输入m 2 1 1 2 m 1 2 2 1时,程序在matrix_input函数中崩溃,无法输出error-2、error-3,怀疑是第二个矩阵的最后一行不存在导致问题。
程序代码
#include <iostream> #include <vector> #include <cassert> using namespace std; // 判断输入是向量还是矩阵 int m_or_v(char m_v) { if(m_v=='v') return 1; else if(m_v=='m') return 2; assert("error"); return 0; } // 输入向量 void vector_input(vector<int> &vector_v) { int row = 0; cin >> row; int cache = 0; for(int i = 0;i<row;i++) { cin >> cache; vector_v.push_back(cache); } } // 输入矩阵 void matrix_input(vector<vector<int>> &matrix_m) { int row = 0; int col = 0; int cache_m = 0; cin >> row; cin >> col; for(int r = 0;r<row;r++) { vector<int> empty = {}; cout << "error-1"; for(int c = 0;c<col;c++) { cin >> cache_m; empty.push_back(cache_m); cout << "error-2"; } matrix_m.push_back(empty); } cout << "error-3"; } // 计算向量点积 void scalar_product(const vector<int> &vector_1,const vector<int> &vector_2) { int value = 0; if(vector_1.size()==vector_2.size()) { for(unsigned long i = 0;i<vector_1.size();i++) { value += (vector_1.at(i)*vector_2.at(i)); } cout << "s" << endl; cout << value; } else cout << "error"; } // 判断运算类型(点积/矩阵-向量积/矩阵乘积) int mult_mode(int mode1, int mode2) { if(mode1==1&&mode2==2) { cout << "error"; return 0; } else if(mode1==1&&mode2==1) return 1; else if((mode1==2&&mode2==1)||(mode1==1&&mode2==2)) return 2; else if(mode1==2&&mode2==2) return 3; else { cout << "error"; return 0; } } // 检查矩阵-向量积是否合法 bool mvp_valid(const vector<vector<int>> &matrix_1, const vector<int> &vector_2) { if(matrix_1.at(0).size()==vector_2.size()) return true; return false; } // 计算矩阵-向量积结果 void mvp_result(const vector<vector<int>> &matrix_1, const vector<int> &vector_2, vector<int> &result) { int cache = 0; for(unsigned long row = 0;row<matrix_1.size();row++) { for(unsigned long col = 0;col<vector_2.size();col++) { cache += matrix_1.at(row).at(col)*vector_2.at(col); } result.push_back(cache); cache = 0; } } // 输出向量 void output_v(vector<int> &vec) { cout << "v " << vec.size() << endl; for(unsigned long i = 0;i<vec.size();i++) { cout << vec.at(i) << " "; } } // 检查矩阵乘积是否合法 bool mxm_valid( const vector<vector<int>> &matrix_1, const vector<vector<int>> &matrix_2) { if(matrix_1.at(0).size()==matrix_2.size()) return true; return false; } // 计算矩阵乘积结果 void mxm_result( const vector<vector<int>> &matrix_1, const vector<vector<int>> &matrix_2, vector<vector<int>> &result_m) { int cache = 0; vector<int> empty; for(unsigned long row = 0;row<matrix_1.size();row++) { result_m.push_back(empty); for(unsigned long col = 0;col<matrix_2.at(row).size();col++) { for(unsigned long row_col = 0;row_col<matrix_2.size();row_col++) { cache+=matrix_1.at(row).at(row_col)*matrix_2.at(row_col).at(col); } result_m.at(row).push_back(cache); cache = 0; } } } // 输出矩阵 void output_m(const vector<vector<int>> &matx) { for(unsigned long col = 0;col<matx.size();col++) { for(unsigned long row = 0;row<matx.size();row++) { cout << matx.at(col).at(row) << " "; } cout << endl; } } // 输出矩阵尺寸 void size_m(const vector<vector<int>> &matx) { cout<<"m "<<matx.size()<<" "<<matx.at(0).size()<<endl; } int main() { char mode_c = ' '; int mode1 = 0; int mode2 = 0; vector<int> vector_1; vector<vector<int>> matrix_1; vector<int> vector_2; vector<vector<int>> matrix_2; // 输入第一个向量/矩阵 cin >> mode_c; mode1 = m_or_v(mode_c); if(mode1==1) { vector_input(vector_1); } else if(mode1==2) { matrix_input(matrix_1); } // 输入第二个向量/矩阵 cin >> mode_c; mode2 = m_or_v(mode_c); if(mode2==1) { vector_input(vector_2); } else if(mode2==2) { cout << "error-10"; matrix_input(matrix_2); cout << "error-11"; } switch(mult_mode(mode1, mode2)) { case 1: scalar_product(vector_1,vector_2); break; case 2: if(mvp_valid(matrix_1, vector_2)==true) { vector<int> result; mvp_result(matrix_1, vector_2, result); output_v(result); } else cout << "error"; break; case 3: if(mxm_valid(matrix_1, matrix_2)==true) { vector<vector<int>> result_m; mxm_result(matrix_1, matrix_2, result_m); size_m(result_m); output_m(result_m); } else cout << "error"; break; } }
问题定位与修复
1. 矩阵乘法函数mxm_result的致命错误
崩溃的核心原因是mxm_result中遍历列时的逻辑错误:
for(unsigned long col = 0;col<matrix_2.at(row).size();col++)
这里用第一个矩阵的行索引row去访问第二个矩阵的行,当第一个矩阵行数(2)大于第二个矩阵行数(1)时,matrix_2.at(row)会触发越界(第二个矩阵只有索引0的行有效)。
修复方案:遍历第二个矩阵的列数,即matrix_2[0].size()(需先确保矩阵非空):
for(unsigned long col = 0; col < matrix_2.at(0).size(); col++)
2. 矩阵输出函数output_m的逻辑错误
原函数颠倒了行和列的遍历顺序,且错误用矩阵行数作为列的遍历范围,导致非方阵输出异常。
修复方案:正确遍历每一行,再遍历该行的所有列:
void output_m(const vector<vector<int>> &matx) { for(unsigned long row = 0; row < matx.size(); row++) { for(unsigned long col = 0; col < matx[row].size(); col++) { cout << matx[row][col] << " "; } cout << endl; } }
3. 空矩阵的边界检查缺失
在mvp_valid、mxm_valid、size_m等函数中,直接访问matrix_1.at(0),若矩阵为空会触发越界。需先添加空矩阵检查:
bool mxm_valid(const vector<vector<int>> &matrix_1, const vector<vector<int>> &matrix_2) { if(matrix_1.empty() || matrix_2.empty()) return false; return matrix_1[0].size() == matrix_2.size(); }
内容的提问来源于stack exchange,提问作者noel76
相关产品推荐
相关产品推荐

