2017-11-11 144 views
0

我想在C++中編寫一個函數,它將兩個已經動態分配的矩陣A,B相乘。我目前正試圖讓乘法代碼工作,然後我會嘗試把它變成一個函數。現在我正在得到各種各樣的錯誤; 「分段故障(核心轉儲)」。我已經縮小到了代碼的乘法部分,但我不知道它有什麼問題。有人能幫助我嗎?我的代碼如下所示。使用動態分配的內存C++乘以矩陣

#include <iostream> 
    #include <cassert> 

    int main() 
    { 
     int rowsA = 5; // number of rows 
     int colsA= 3; // number of coloumns 
     // dynamically allocating A 
     double** A; 
     A = new double* [rowsA]; 
     A[0] = new double [rowsA*colsA]; 
     for (int i = 1; i < rowsA; i++) 
     { 
      A[i] = A[i-1] + colsA; 
     } 

     // Storing elements of matrix A 
     for(int i = 0; i < rowsA; ++i) 

     { 
      for(int j = 0; j < colsA; ++j) 

      { 

      std::cout << "Enter element A" << i + 1 << j + 1 << " : "; 
      std::cin >> A[i][j]; 

      } 
     } 

     int rowsB = 3; // number of rows 
     int colsB = 5; // number of coloumns 
     // dynamically allocating B 
     double** B; 
     B = new double* [rowsB]; 
     B[0] = new double [rowsB*colsB]; 
     for (int i = 1; i < rowsB; i++) 
     { 
      B[i] = B[i-1] + colsB; 
     } 

     // Storing elements of matrix B 
     for(int i = 0; i < rowsB; ++i) 

     { 
      for(int j = 0; j < colsB; ++j) 

      { 

      std::cout << "Enter element B" << i + 1 << j + 1 << " : "; 
      std::cin >> B[i][j]; 

      } 
     } 

     // checking matrix multiplication qualification 
     assert(colsA == rowsB); 

     // dynamically allocating C 
     double** C; 
     C = new double* [rowsA]; 
     C[0] = new double [rowsA*colsB]; 
     for (int i = 1; i < rowsA; i++) 
     { 
      C[i] = C[i-1] + colsB; 
     } 

     // Initializing elements of matrix C to 0 
     for(int i = 0; i < rowsA; ++i) 

     { 
      for(int j = 0; j < colsB; ++j) 
      { 

      C[i][j]=0; 

      } 
     } 

     // multiplication 
     for(int i = 0; i < rowsA; ++i) 

     { 
      for(int j = 0; j < colsB; ++j) 

      { 
      for(int k = 0; k < colsB; ++k) 
      { 
       C[i][j] += A[i][k] * B[k][j]; 

      } 
      } 
     } 

     // Displaying the multiplication of matrices A, B 

     std::cout<< "Matrix C: " << std::endl; 

     for(int i = 0; i < rowsA; ++i) 

     { 
      for(int j = 0; j < colsB; ++j) 

      { 

       std::cout << " " << C[i][j]; 

       if(j == colsB-1) 

       { 
        std::cout << std::endl; 

       } 
      } 
     } 
     // deallocation 
     delete[] C[0]; 
     delete[] C; 
     delete[] B[0]; 
     delete[] B; 
     delete[] A[0]; 
     delete[] A; 
    } 
+0

您需要在2D動態分配數組分配各行:https://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new – Brandon

+0

你好。謝謝。我已經做到了。當我註釋掉乘法並只要求我的代碼打印C(初始化爲全0)時,它將它打印到控制檯就可以了。當我修改代碼時,它也會打印A和B.所以,我認爲,乘法部分有些問題。 – Rebecca

回答

1

首先,你說你正在正確分配矩陣,但我沒有看到任何證據。您正在分配一組指針並僅初始化第一個索引。例如,A[0]。這是不正確的。你需要分配EACH ROW。

您有:

double** A; 
A = new double* [rowsA]; 
A[0] = new double [rowsA*colsA]; //Incorrect. You only allocated A[0]. 

您需要分配A [0]至A [rowsA - 1] ..

接下來,你的循環乘法(內環路最多)不正確。它應該是:

迭代ColsA爲內部循環。

您有:

for(int i = 0; i < rowsA; ++i) 
    { 
     for(int j = 0; j < colsB; ++j) 
     { 
     for(int k = 0; k < colsB; ++k) //ColsB is incorrect. Should be colsA.. 
     { 
      C[i][j] += A[i][k] * B[k][j]; //Segfaults here due to bad iteration.. 

     } 
     } 
    } 

下面是正確的:

#include <iostream> 
#include <cassert> 

double** create_matrix(int rows, int cols) 
{ 
    double** mat = new double* [rows]; //Allocate rows. 
    for (int i = 0; i < rows; ++i) 
    { 
     mat[i] = new double[cols](); //Allocate each row and zero initialize.. 
    } 
    return mat; 
} 

void destroy_matrix(double** &mat, int rows) 
{ 
    if (mat) 
    { 
     for (int i = 0; i < rows; ++i) 
     { 
      delete[] mat[i]; //delete each row.. 
     } 

     delete[] mat; //delete the rows.. 
     mat = nullptr; 
    } 
} 

int main() 
{ 
    int rowsA = 5; // number of rows 
    int colsA= 3; // number of coloumns 
    double** matA = create_matrix(rowsA, colsA); 


    int rowsB = 3; // number of rows 
    int colsB = 5; // number of coloumns 
    double** matB = create_matrix(rowsB, colsB); 


    //Checking matrix multiplication qualification 
    assert(colsA == rowsB); 


    double** matC = create_matrix(rowsA, colsB); 

    //Multiplication 
    for(int i = 0; i < rowsA; ++i) 
    { 
     for(int j = 0; j < colsB; ++j) 
     { 
      for(int k = 0; k < colsA; ++k) //ColsA.. 
      { 
       matC[i][j] += matA[i][k] * matB[k][j]; 
      } 
     } 
    } 


    //Clean up.. 
    destroy_matrix(matA, rowsA); 
    destroy_matrix(matB, rowsB); 
    destroy_matrix(matC, rowsA); 
}