2014-09-19 85 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)。