使用动态分配的内存的C ++乘法矩阵

时间:2017-11-11 18:52:29

标签: c++ matrix-multiplication dynamic-allocation

我正在尝试用C ++编写一个函数,该函数将两个已动态分配的矩阵A,B相乘。我目前正在尝试使乘法代码工作,然后我将尝试将其转换为函数。现在我得到了各种错误; "分段错误(核心转储)"。我把它缩小到我的代码的乘法部分,但我不知道它有什么问题。有谁可以帮助我吗?我的代码如下所示。

    #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;
     }

1 个答案:

答案 0 :(得分:1)

首先,你说你正在正确分配矩阵,但我没有看到任何证据。您正在分配一个指针数组,并且仅初始化第一个索引.. A[0]。这是不正确的。你需要分配EACH ROW。

你有:

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

您需要通过A [rowsA - 1] ..

分配A [0]

接下来,你的乘法循环(最里面的循环)是不正确的。它应该是:

迭代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);
}