2017-11-11 169 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); 
}