C++矩阵类重载<<运算符后输出错误值及异常问题排查
问题分析与修复方案
我来帮你排查这段代码里的问题,核心问题集中在矩阵乘法逻辑、对象初始化和异常处理这几个方面:
1. 矩阵乘法的核心逻辑错误(乱码直接原因)
你的multiply函数计算结果矩阵元素时,用了直接赋值操作:
B.mat[i * A.col + j] = this->mat[i * this->col + k] * A.mat[k * A.col + j];
但矩阵乘法的定义是每个元素是对应行与列所有乘积的累加和,不是单次赋值。加上你创建的Matrix B如果没有初始化内部数组,mat里全是内存中的随机垃圾值,最终输出自然会出现乱码。
正确的做法是先把B的所有元素初始化为0,然后用+=做累加操作。
2. 构造函数与对象初始化问题
你调用Matrix B = Matrix(this->row, A.col);创建结果矩阵,但你提供的构造函数只有三个参数的版本(row, col, double*)。如果这个两参数构造函数是你自定义的,一定要确保它会把内部的mat数组所有元素初始化为0,否则B的初始值就是未定义的垃圾数据。
3. 异常抛出的错误用法
你用了throw new std::exception("...");,这会抛出一个std::exception*指针而非异常对象本身,会导致两个问题:
- 捕获异常时需要专门处理指针,还得手动
delete否则会内存泄漏; - C++标准异常处理的最佳实践是抛出值而非指针。
应该改成:
throw std::exception("Math::Matrix::multiply : cannot multiply!");
4. Main函数的语法与内存问题
- 你直接写
A = ...和B = ...,但没有声明变量类型,这是语法错误,需要明确声明:Math::Matrix A(2, 3, new double[6]{ 1, 2, 3, 4, 5, 6 }); Math::Matrix B(3, 4, new double[12]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2 }); - 你用
new创建的double数组没有用delete[]释放,会造成内存泄漏,建议后续改用智能指针或在构造函数内部处理初始值的内存管理。
修复后的multiply函数示例
const Math::Matrix Math::Matrix::multiply(Matrix & A) const { if (!this->is_multipliable(A)) { throw std::exception("Math::Matrix::multiply : cannot multiply!"); } Matrix B(this->row, A.col); // 初始化B的所有元素为0 std::fill(B.mat, B.mat + B.row * B.col, 0.0); // 调整循环顺序为i->k->j,提升缓存命中率 for (int i = 0; i < this->row; i++) { for (int k = 0; k < this->col; k++) { double current_val = this->mat[i * this->col + k]; for (int j = 0; j < A.col; j++) { B.mat[i * A.col + j] += current_val * A.mat[k * A.col + j]; } } } return B; }
内容的提问来源于stack exchange,提问作者user5876164
相关产品推荐
相关产品推荐

