You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++矩阵乘法函数结果异常:输出值与调试结果不符求助

矩阵乘法函数输出异常排查

问题背景

编写了C++矩阵乘法函数multiplication,该函数接收两个ifstream引用,从文件读取矩阵维度与数据,计算乘积后写入output.txt,最后返回ofstream对象。

输入文件内容

  • 1.txt:
1 3
1 2 3
  • 2.txt:
3 1
4 5 6

预期输出

1 1
32

实际输出

1 1
-3.424e+26

调试时显示计算结果为正确的32,但输出结果异常,相关代码如下:

ofstream multiplication(ifstream& lhs, ifstream& rhs) {
    int rows_lhs = 0, cols_lhs = 0;
    int rows_rhs = 0, cols_rhs = 0;
    if (!lhs.eof() && !rhs.eof()) {
        lhs >> rows_lhs >> cols_lhs;
        rhs >> rows_rhs >> cols_rhs;
    }
    float matrix_lhs[rows_lhs][cols_lhs];
    float matrix_rhs[rows_rhs][cols_rhs];
    float el = 0.0;
    for (size_t i = 0; i < rows_lhs; ++i) {
        for (size_t j = 0; j < cols_lhs; ++j) {
            lhs >> el;
            matrix_lhs[i][j] = el;
        }
    }
    for (size_t i = 0; i < rows_rhs; ++i) {
        for (size_t j = 0; j < cols_rhs; ++j) {
            rhs >> el;
            matrix_rhs[i][j] = el;
        }
    }
    float matrix_res[rows_lhs][cols_rhs];
    float left_el = 0.0;
    float right_el = 0.0;
    for (size_t i = 0; i < rows_lhs; ++i) {
        for (size_t j = 0; j < cols_rhs; ++j) {
            for (size_t k = 0; k < cols_lhs; ++k) {
                left_el = matrix_lhs[i][k];
                right_el = matrix_rhs[k][j];
                matrix_res[i][j] += left_el * right_el;
            }
        }
    }
    ofstream out;
    out.open("output.txt");
    out << rows_lhs << ' ' << cols_rhs << '\n';
    for (size_t i = 0; i < rows_lhs; ++i) {
        for (size_t j = 0; j < cols_rhs; ++j) {
            out << matrix_res[i][j] << ' ';
        }
        out << '\n';
    }
    out.close();
    return out;
}

int main(int argc, char* argv[]) {
    ifstream infile_1("1.txt");
    ifstream infile_2("3.txt");
    ofstream out = multiplication(infile_1, infile_2);
    float res = 0;
    while (!out.eof()) {
        out << res;
    }
}

问题分析与修复

1. 结果矩阵未初始化,累加前存在垃圾值

float matrix_res[rows_lhs][cols_rhs];是栈上分配的非标准变长数组(VLA),C++标准不支持该写法(仅部分编译器提供扩展支持),且栈数组默认不会初始化,元素值为内存中的随机垃圾值。后续直接执行matrix_res[i][j] += left_el * right_el;时,是在垃圾值基础上累加计算结果,最终输出的是垃圾值与正确值的总和,这是输出异常的核心原因。

调试环境通常会将栈内存初始化为0,因此调试时能看到正确结果,但实际运行时栈内存为随机值,导致输出错误。

修复方式:初始化结果矩阵所有元素为0,或改用std::vector创建动态矩阵并自动初始化。

2. 返回已关闭的ofstream对象,main函数错误复用

multiplication函数中执行了out.close();,返回的ofstream对象已处于关闭状态。main函数接收该对象后,执行while (!out.eof()) { out << res; }的逻辑完全错误:关闭的流无法写入,且!out.eof()不是正确的文件循环判断方式,会导致无意义的无效操作。

同时,main函数中打开的第二个输入文件是3.txt,与实际输入文件2.txt不符,会导致读取失败,矩阵数据为垃圾值(调试时可能文件名正确,因此未暴露该问题)。

修复方式:移除手动关闭out的代码(ofstream析构时会自动关闭文件),修正输入文件名,删除main中错误的写入循环。

3. 非标准变长数组的使用

C++标准不支持float matrix_lhs[rows_lhs][cols_lhs];这种变长数组写法,会降低代码可移植性,建议改用std::vector<std::vector<float>>动态创建二维矩阵。

4. 文件读取未做错误检查

代码仅通过!lhs.eof() && !rhs.eof()判断是否读取维度,但未检查lhs >> rows_lhs >> cols_lhs等读取操作是否成功。若文件格式错误或文件不存在,会导致维度为0,后续数组访问越界。

修复方式:添加读取操作的有效性检查,避免无效数据进入后续计算。

修复后的完整代码

#include <fstream>
#include <vector>

std::ofstream multiplication(std::ifstream& lhs, std::ifstream& rhs) {
    int rows_lhs = 0, cols_lhs = 0;
    int rows_rhs = 0, cols_rhs = 0;
    // 检查维度读取是否成功
    if (!(lhs >> rows_lhs >> cols_lhs) || !(rhs >> rows_rhs >> cols_rhs)) {
        std::ofstream empty_out;
        return empty_out;
    }
    // 使用vector创建并初始化矩阵
    std::vector<std::vector<float>> matrix_lhs(rows_lhs, std::vector<float>(cols_lhs, 0.0f));
    std::vector<std::vector<float>> matrix_rhs(rows_rhs, std::vector<float>(cols_rhs, 0.0f));
    
    float el = 0.0f;
    for (int i = 0; i < rows_lhs; ++i) {
        for (int j = 0; j < cols_lhs; ++j) {
            lhs >> el;
            matrix_lhs[i][j] = el;
        }
    }
    for (int i = 0; i < rows_rhs; ++i) {
        for (int j = 0; j < cols_rhs; ++j) {
            rhs >> el;
            matrix_rhs[i][j] = el;
        }
    }
    // 初始化结果矩阵为0
    std::vector<std::vector<float>> matrix_res(rows_lhs, std::vector<float>(cols_rhs, 0.0f));
    for (int i = 0; i < rows_lhs; ++i) {
        for (int j = 0; j < cols_rhs; ++j) {
            for (int k = 0; k < cols_lhs; ++k) {
                matrix_res[i][j] += matrix_lhs[i][k] * matrix_rhs[k][j];
            }
        }
    }
    std::ofstream out("output.txt");
    if (out.is_open()) {
        out << rows_lhs << ' ' << cols_rhs << '\n';
        for (int i = 0; i < rows_lhs; ++i) {
            for (int j = 0; j < cols_rhs; ++j) {
                out << matrix_res[i][j] << ' ';
            }
            out << '\n';
        }
    }
    return out;
}

int main(int argc, char* argv[]) {
    std::ifstream infile_1("1.txt");
    std::ifstream infile_2("2.txt"); // 修正文件名
    std::ofstream out = multiplication(infile_1, infile_2);
    return 0;
}

内容的提问来源于stack exchange,提问作者nameisnoname

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 19:34:52