【问题标题】:Matrix multiplication in C++ gives Runtime ErrorC ++中的矩阵乘法给出运行时错误
【发布时间】:2014-11-14 12:55:40
【问题描述】:

我正在使用以下 C++ 代码进行矩阵乘法,它在 SIZE = 500 时运行良好。但是当 SIZE = 600 或更高时,代码会失败。 (运行时错误)

我在 Ideone.com 上运行它 它输出 “运行时错误时间:0 内存:3292 信号:11”

在我的本地机器上也出现错误

#include <cstdlib>
#include<iostream>
#include <stdio.h>
#include <sys/time.h>

using namespace std;
class Timer {
private:

timeval startTime;

public:

void start(){
    gettimeofday(&startTime, NULL);
}

double stop(){
    timeval endTime;
    long seconds, useconds;
    double duration;

    gettimeofday(&endTime, NULL);

    seconds  = endTime.tv_sec  - startTime.tv_sec;
    useconds = endTime.tv_usec - startTime.tv_usec;

    duration = seconds + useconds/1000000.0;

    return duration;
}

static void printTime(double duration){
    printf("%5.6f seconds\n", duration);
}
};
using namespace std;
const int SIZE = 600; // for size*size matrix 
void MultiplyMatricesSequential(double a[][SIZE],double b[][SIZE],double ans[][SIZE]);
int i,j,k;
double s;
/*
 * 
 */
int main(int argc, char** argv) {
double a[SIZE][SIZE], b[SIZE][SIZE], ans[SIZE][SIZE];
// assign the numbers for matrix a and b
for (i = 0; i < SIZE; i++) {
    for (j = 0; j < SIZE; j++) {
        a[i][j]=(double)rand()/RAND_MAX;
        b[i][j]=(double)rand()/RAND_MAX;
    }
}
MultiplyMatricesSequential(a,b,ans);
return 0;
}

void MultiplyMatricesSequential(double a[][SIZE],double b[][SIZE],double ans[][SIZE])
{  
 Timer timer = Timer();
    timer.start(); 
for (i = 0; i < SIZE; i++) {
    for (j = 0; j < SIZE; j++) {
        for (k = 0; k < SIZE; k++)
            s += a[i][k] * b[k][j];
        ans[i][j] = s;         
        s = 0.0;
    }

}

double duration = timer.stop();
cout << "Sequential Method time elapsed for SIZE " << SIZE << " : ";
timer.printTime(duration);

 }

那么我在这里做错了什么?

注意: 不使用定时器时还是一样。

        #include <cstdlib>
        #include<iostream>
        #include <stdio.h>
        #include <sys/time.h>

        using namespace std;
        const int SIZE = 500; // for size*size matrix 
        void MultiplyMatricesSequential(double a[][SIZE],double b[][SIZE],double ans[][SIZE]);
        int i,j,k;
        double s;
        /*
         * 
         */
        int main(int argc, char** argv) {
          double a[SIZE][SIZE], b[SIZE][SIZE], ans[SIZE][SIZE];
            // assign the numbers for matrix a and b
            for (i = 0; i < SIZE; i++) {
                for (j = 0; j < SIZE; j++) {
                    a[i][j]=(double)rand()/RAND_MAX;
                    b[i][j]=(double)rand()/RAND_MAX;
                }
            }
            MultiplyMatricesSequential(a,b,ans);
            return 0;
        }

        void MultiplyMatricesSequential(double a[][SIZE],double b[][SIZE],double ans[][SIZE])
        {  

            for (i = 0; i < SIZE; i++) {
                for (j = 0; j < SIZE; j++) {
                    for (k = 0; k < SIZE; k++)
                        s += a[i][k] * b[k][j];
                    ans[i][j] = s;         
                    s = 0.0;
                }

            }


        }

【问题讨论】:

  • 我猜你的内存不足了。
  • 所以我不能将 2 个大小为 600*600 的矩阵相乘吗 :(
  • 不能在栈上声明三个 600x600 double 数组(自动存储)。
  • 不知道。我会将该错误剪切并粘贴到谷歌中,看看它告诉你什么。 (600*600 双倍)*(8 字节/双倍) ~ 2.8MB。没那么大。你将有两个矩阵和结果,所以乘以 3。仍然没有那么多内存。你的机器上有多少?

标签: c++ runtime-error


【解决方案1】:

首先 - 如果您要读取一些大小未知的数据 - 我强烈建议您使用动态内存分配来存储它,而不是预先分配一些固定大小的数组。如果这不是你的情况,或者你不想听我的建议,那么最好将那些更大的数组分配在全局命名空间中,而不是在堆栈上。这意味着您的代码将如下所示:

    using namespace std;
            const int SIZE = 500; // for size*size matrix 
            void MultiplyMatricesSequential(double a[][SIZE],double b[][SIZE],double ans[][SIZE]);
            int i,j,k;
            double s;
            /*
             * 
             */
    double g_a[SIZE][SIZE], g_b[SIZE][SIZE], g_ans[SIZE][SIZE];

            int main(int argc, char** argv) {

                // assign the numbers for matrix a and b
                for (i = 0; i < SIZE; i++) {
                    for (j = 0; j < SIZE; j++) {
                        g_a[i][j]=(double)rand()/RAND_MAX;
                        g_b[i][j]=(double)rand()/RAND_MAX;
                    }
                }
                MultiplyMatricesSequential(g_a,g_b,g_ans);
                return 0;
            }

//..........

请注意,我在您的“矩阵”名称中添加了“g_”前缀。

还知道堆栈或“本地存储”用于存储临时变量和函数参数,这些临时变量和函数参数将在调用它们所属的函数时分配给它,并在返回时“删除”。但是堆栈大小是固定的,如果其中没有空间来创建它们,程序就会崩溃。另一方面,全局变量没有内存限制,因为它们需要的空间是在编译时自动分配的。它们的生命周期与您的“矩阵”一样等于应用程序运行时间,因为您已将它们创建到“主”函数中。所以现在的选择很简单——你是想浪费程序时间分配和“删除”数据,还冒着堆栈溢出的风险,还是轻松获取大数据——使用全局变量。或者,如果使用真实数据 - 通过动态内存分配变得更加友好。

【讨论】:

    【解决方案2】:

    底线是,虽然 600×600 矩阵并没有那么大,但 堆栈内存 限制(即非动态分配的变量的限制)相当低(参见例如 @ 987654321@).

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-17
      • 1970-01-01
      • 2013-12-18
      • 2022-07-21
      • 2019-03-24
      相关资源
      最近更新 更多