C++ 矩阵乘法向量 out_of_range 异常

Posted

技术标签:

【中文标题】C++ 矩阵乘法向量 out_of_range 异常【英文标题】:C++ Matrix Multiplication Vector out_of_range Exception 【发布时间】:2016-09-04 20:39:32 【问题描述】:

我正在编写一个 C++ 程序来乘以二维向量形式的矩阵。矩阵具有预设尺寸并包含随机生成的双精度值。由于某种我无法弄清楚的原因,当我运行程序时会抛出一个 out_of_range 异常:

在 MatMulSeq.exe 中的 0x7620dae8 处引发异常:Microsoft C++ 异常:内存位置 0x00b3eb20 处的 std::out_of_range。

抛出异常:MatMulSeq.exe 中的“System.Runtime.InteropServices.SEHException”

MatMulSeq.exe 中出现“System.Runtime.InteropServices.SEHException”类型的未处理异常

附加信息:外部组件已抛出异常。

我尝试使用断点来确定抛出异常的位置,并且似乎是在填充 vec_b 时,但这可能是错误的。

我基本上是从我在互联网上找到的其他已确认可以运行的程序中复制了该程序的方法,所以我不确定为什么我的失败了。

这是我的代码:

#include <iostream>
#include <vector>
#include <ctime>
#include <cstdlib>

using namespace std;

double randNum()

    double min = 1.0;
    double max = 1000000.0;
    return ((1000000.0 - 1.0) * ((double)rand() / (double)RAND_MAX) + min);


int main()

    // Seed srand
    unsigned seed = time(0);
    srand(seed);

    // Matrix setup

    // # columns of 1st matrix must = # rows of 2nd matrix
    // Result will have same # rows as 1st and same # columns as 2nd
    int RowA = 50,
        ColA = 20,
        RowB = 20,
        ColB = 25,
        RowC = RowA,
        ColC = ColB;

    cout.precision(2);

    vector<vector<double>> vec_a;
    vec_a.resize(RowA);
    for (int i = 0; i < RowA; ++i)
        vec_a[i].resize(ColA);

    vector<vector<double>> vec_b;
    vec_b.resize(RowB);
    for (int i = 0; i < RowB; ++i)
        vec_a[i].resize(ColB);

    vector<vector<double>> vec_c;
    vec_c.resize(RowC);
    for (int i = 0; i < RowC; ++i)
        vec_c[i].resize(ColC);

    // Fill matrices a and b
    for (int i = 0; i < RowA; i++)
    
        for (int j = 0; j < ColA; j++)
        
            vec_a.at(i).at(j) = randNum();
        
    

    for (int i = 0; i < RowB; i++)
    
        for (int j = 0; j < ColB; j++)
        
            vec_b.at(i).at(j) = randNum();
        
    

    // Fill matrix c by multiplying matrices a and b
    for (int i = 0; i < RowA; i++)
    
        for (int j = 0; j < ColB; j++)
        
            vec_c.at(i).at(j) = 0;
            for (int k = 0; k < RowB; k++)
            
                vec_c.at(i).at(j) = vec_c.at(i).at(j) + (vec_a.at(i).at(k) * vec_b.at(k).at(j));
            
        
    

    // Display
    for (int i = 0; i < RowA; i++)
    
        for (int j = 0; j < ColA; j++)
        
            cout << fixed << vec_a.at(i).at(j) << endl;
        
    
    cout << endl << endl << endl;
    for (int i = 0; i < RowB; i++)
    
        for (int j = 0; j < ColB; j++)
        
            cout << fixed << vec_b.at(i).at(j) << endl;
        
    
    cout << endl << endl << endl;
    for (int i = 0; i < RowC; i++)
    
        for (int j = 0; j < ColC; j++)
        
            cout << fixed << vec_c.at(i).at(j) << endl;
        
    



    system("pause");
    return 0;

如果我在这里要求太多,我很抱歉,但我已经坚持了几个小时,我真的可以使用一些指导。谢谢

【问题讨论】:

这不是您要求的,但您应该学习如何使用外部库进行此类操作(矩阵乘法)。重新发明***是没有意义的。了解如何使用 lapack 库中的 dgemm 函数,它将有效地为您执行乘法运算。 netlib.org/lapack/explore-html/d7/d2b/dgemm_8f.html 你使用调试器了吗?不应该花费数小时来确定其中一个 at() 调用引发了异常。 @PaulMcKenzie 真的不知道怎么做,我通常不使用 C++ 和 Visual Studio。我只需要为并行编程课程编写这个程序。 每个主要(现在可能是每个编译器)都带有一个调试器,而不仅仅是 Visual Studio。其次,如果您阅读documentation to vector::at(),您会看到如果使用的索引超出向量范围,它会引发向您报告的异常std::out_of_range 我基本上是从我在互联网上找到的其他确认可以工作的程序中复制了这个程序的方法,所以我不确定为什么我的失败了。 --那么你怎么知道你刚刚从互联网上复制的代码的价值呢?代码写得很糟糕,只是因为vectors 是如何初始化的。您无需编写循环调用resize 来初始化std::vector&lt;std::vector&lt;T&gt;&gt; 【参考方案1】:

vector<vector<double>> vec_b;
vec_b.resize(RowB);
for (int i = 0; i < RowB; ++i)
    vec_a[i].resize(ColB);

您正在调整 vec_a 行的大小,而不是 vec_b,因此 vec_b 中的行都是空的。

【讨论】:

不错!非常感谢。 不知道你为什么被否决,如果我是一个足够高的代表,我会投赞成票。再次感谢。 @possum_pendulum 不用担心。如果这个答案有帮助,您可以点击旁边的绿色勾号接受它。 整 4 行代码可以用 1 行来编写。 vector&lt;vector&lt;double&gt;&gt; vec_b(RowB, std::vector&lt;double&gt;(ColB));也许这就是投反对票的原因。 @PaulMcKenzie 可能,我只是复制 OP 的代码来修复错误,而不是宽恕它。无论如何,很好的改进建议。

以上是关于C++ 矩阵乘法向量 out_of_range 异常的主要内容,如果未能解决你的问题,请参考以下文章

稀疏矩阵与密集矩阵乘法 C++ Tensorflow

C++:未处理的异常:内存位置的 std::out_of_range

向量矩阵乘法、浮点向量、二进制矩阵

向量乘法(矩阵乘法)奇数输出的向量

矩阵和向量的乘法顺序

GLM的向量矩阵乘法行为?