2014-09-19 94 views
0

我使用以下C++代码来执行矩阵乘法,并且它对SIZE = 500运行正常。但是,当SIZE = 600或更高时代码将失败。 (运行时错误)C++中的矩阵乘法给出运行时错误

我跑它Ideone.com 它。OUPUTS “运行时错误时间: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; 
       } 

      } 


     } 
+0

我猜你用完了内存。 – duffymo 2014-09-19 20:56:17

+0

所以我不能乘以600 * 600大小的两个矩阵:( – prime 2014-09-19 20:57:21

+0

)你不能在栈上声明三个600x600'double'数组(自动存储)。 – Blastfurnace 2014-09-19 20:59:00

回答

2

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

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_”前缀。

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

+0

实际上这解决了这个问题。谢谢:) – prime 2014-09-20 05:45:16

0

底线是,虽然一个600×600矩阵并不大,则栈存储器限制(即,对于不动态分配的变量的极限)是相当低的(参见例如here)。