【问题标题】:Matrix Multiplication for any proper order with dynamic memory allocation具有动态内存分配的任何正确顺序的矩阵乘法
【发布时间】:2014-05-06 14:16:24
【问题描述】:

我正在尝试执行矩阵乘法(动态内存分配),用户可以输入任何有效的矩阵乘法顺序(即 column1=row2)。 两个矩阵的相同阶数(2x2 或 3x3)的输出会导致正确的计算,但像 mat1 2x3 & mat2 3x2.. 这样的阶数会导致分段错误。当我事先进行内存分配时,我无法确定我是如何访问任何非法内存的。

请多多指教,如果我犯了一些愚蠢的错误,请原谅我......

以下是完整代码:

#include<stdio.h>
#include<stdlib.h>


main(){
int **mat1, **mat2,**res,i,j,r1,c1,r2,c2;

printf("\nEnter the Order of the First matrix...\n");
scanf("%d %d",&r1,&c1);
printf("\nEnter the Order of the Second matrix...\n");
scanf("%d %d",&r2,&c2);

if(c1!=r2){
    printf("Invalid Order of matrix");
    exit(EXIT_SUCCESS);
}

mat1= (int**) malloc(r1*sizeof(int*));

for(i=0;i<c1;i++)
    mat1[i]=(int*)malloc(c1*sizeof(int));

mat2= (int**) malloc(r2*sizeof(int*));

for(i=0;i<c2;i++)
    mat2[i]=(int*)malloc(c2*sizeof(int));

res=(int**)calloc(r1,sizeof(int*));

for(i=0;i<c2;i++)
    res[i]=(int*)calloc(c2,sizeof(int));

//Input Matrix1
    for(i=0;i<r1;i++)
        for(j=0;j<c1;j++)
            scanf("%d",&mat1[i][j]);
//Input Matrix2
    for(i=0;i<r2;i++)
        for(j=0;j<c2;j++)
            scanf("%d",&mat2[i][j]);

//Printing Input Matrix 1 and 2

printf("\n Entered Matrix 1: \n");
for(i=0;i<r1;i++){
    for(j=0;j<c1;j++)
        printf("%d ",mat1[i][j]);
    printf("\n");
}

printf("\n Entered Matrix 2: \n");
for(i=0;i<r2;i++){
    for(j=0;j<c2;j++)
        printf("%d ",mat2[i][j]);
    printf("\n");
}       

//Computation


//Multiplication

    for(i=0;i<r1;i++){
        for(j=0;j<c2;j++){
                res[i][j]=0;
                for(k=0;k<c1;k++)
                    res[i][j]+= mat1[i][k]*mat2[k][j];

        }
        printf("\n");
    }


   printf("\nThe Multiplication of two matrix is\n");
   for(i=0;i<r1;i++){
       printf("\n");
       for(j=0;j<c2;j++)
            printf("%d\t",res[i][j]);   
   }
    printf("\n");

/*  Addition
for(i=0;i<r1;i++)
        for(j=0;j<c2;j++)
                res[i][j]=mat1[i][j]+mat2[i][j];


printf("\nThe Addition of two matrix is\n");
   for(i=0;i<r1;i++){
       printf("\n");
       for(j=0;j<c2;j++)
            printf("%d\t",res[i][j]);
    }
*/


return 0;}

【问题讨论】:

  • 很久没碰C了,你确定scanf需要&吗?它们只是指针,对吗?
  • scanfs 在这里没问题。
  • 是的 Ritikesh,我在这里单独访问数组元素,这就是为什么我需要将 & 放入 scanf...

标签: c matrix dynamic-memory-allocation


【解决方案1】:

在计算矩阵乘法时,您必须从 0 到 c2 运行 k 循环,而不是从 0 到 c1。

【讨论】:

    【解决方案2】:

    我在下面附上了矩阵乘法的代码,用于动态内存分配的任何正确顺序

    为了完整起见,我使用了 3 种不同的矩阵乘法方法:一个函数 double** multMatrixpf(参见等效函数 Fortran/Pascal)和两个子例程/过程(Fortran/Pascal 之类),其中首先 void multMatrixp 你需要 @987654323 @ 外部和第二个子程序void multMatrixpp 矩阵c1 在子程序内部分配。这三种方法都给出了相同的结果。

    我也使用了不同的方法来初始化数组。

    #include <stdio.h>
    #include <stdlib.h>
    void allocate_mem(double*** arr, int rows, int cols);
    void deallocate_mem(double*** arr, int n);
    double** readMatrixf(int rows, int cols);
    void readMatrix(double ***a, int rows,int cols);
    void printMatrix(double** a, int rows, int cols);
    void printMatrixE(double** a, int rows, int cols);
    void multMatrixp(double **A, double **B, double **C,int r1,int c1,int r2,int c2);
    void multMatrixpp(double **A, double **B, double ***C,int ro1,int co1,int ro2,int co2);
    double** multMatrixpf(double **A, double **B, int ro1,int co1,int ro2,int co2);
    
    //______________________________________________________________________________
    
    int main()
    {
       int ro1, co1, ro2, co2;
       double **a1, **b1, **c1;    
    
    ro1=2; co1=3;
    ro2=3; co2=4;
    
    printf("Ex1:__________________________________________________"
        "__________________________ \n");
    
    
    double (*(a[])) = {
    (double[]) { 1, 3, 5},
    (double[]) {2, 4, 0}};
    
    
    double (*(b[])) = {
    (double[]) {6, 2, 4, 8},
    (double[]) {1, 7, 0, 9},
    (double[]) {0, 3, 5, 1}};
    
    
    printMatrix(a,ro1,co1);    
    printMatrix(b,ro2,co2);
    
    
    printf("MatMult \n");
    double **c;
    allocate_mem(&c,ro1,co2);
    multMatrixp(a, b, c, ro1, co1, ro2, co2);  
    printMatrix(c,ro1,co2);        
    printMatrixE(c,ro1,co2);      
    
    deallocate_mem(&c,ro1);  
    
    
    printf("Ex2:__________________________________________________"
        "__________________________ \n");
    
    scanf("%d%d", &ro1, &co1);
    readMatrix(&a1,ro1,co1);
    printMatrix(a1,ro1,co1); 
    //deallocate_mem(&a1,ro1); 
    //printMatrix(a1,ro1,co1); 
    
    
    scanf("%d%d", &ro2, &co2);
    readMatrix(&b1,ro2,co2);
    printMatrix(b1,ro2,co2);
    
    printf("MatMult \n");
    multMatrixpp(a1, b1, &c1, ro1, co1, ro2, co2);  
    printMatrix(c1,ro1,co2); 
    printMatrixE(c1,ro1,co2);      
    
    deallocate_mem(&a1,ro1); 
    deallocate_mem(&b1,ro2);
    deallocate_mem(&c1,ro1);  
    
    
    printf("Ex3:__________________________________________________"
        "__________________________ \n");
    
    scanf("%d%d", &ro1, &co1);
    a1=readMatrixf(ro1,co1);
    printMatrix(a1,ro1,co1); 
    //deallocate_mem(&a1,ro1); 
    //printMatrix(a1,ro1,co1); 
    
    
    scanf("%d%d", &ro2, &co2);
    b1=readMatrixf(ro2,co2);
    printMatrix(b1,ro2,co2);
    
    printf("MatMult \n");
    c1=multMatrixpf(a1, b1, ro1, co1, ro2, co2);  
    printMatrix(c1,ro1,co2); 
    printMatrixE(c1,ro1,co2);      
    
    deallocate_mem(&a1,ro1); 
    deallocate_mem(&b1,ro2);
    deallocate_mem(&c1,ro1);  
    
    
    
        return 0;
    }
    
    //______________________________________________________________________________
    void allocate_mem(double*** arr, int rows, int cols)
    {
      int i;
      *arr = (double**)malloc(rows*sizeof(double*));
      for( i=0; i<rows; i++)
        (*arr)[i] = (double*)malloc(cols*sizeof(double));
    } 
    
    //______________________________________________________________________________
    void deallocate_mem(double*** arr, int rows){
     int i;
        for (i = 0; i < rows; i++)
            free((*arr)[i]);
        free(*arr); 
    }
    
    //______________________________________________________________________________
    double** readMatrixf(int rows, int cols)
    {
    double    **a; // Define a local pointer to keep rest of the code intact
    int i, j;
    
    a= (double**) malloc(rows*sizeof(double*));
    for(i=0;i<rows;i++)
    a[i]=(double*)malloc(cols*sizeof(double));
    
        for(i=0;i<rows;i++)
            for(j=0;j<cols;j++)
                scanf("%lf",&a[i][j]);
       return a;            
    
    }
    
    //______________________________________________________________________________
    
    void readMatrix(double ***a, int rows,int cols)
    {
       int i, j;
    
    *a= (double**) malloc(rows*sizeof(double*));
    for(i=0;i<rows;i++)
    (*a)[i]=(double*)malloc(cols*sizeof(double));
        for(i=0;i<rows;i++)
            for(j=0;j<cols;j++)
                scanf("%lf",&(*a)[i][j]);
    }
    
    //______________________________________________________________________________
    void printMatrix(double** a, int rows, int cols)
    {
        int i, j;
       printf("Matrix[%d][%d]\n",rows,cols);    
       for(i=0;i<rows;i++){
          for(j=0;j<cols;j++)
          printf("%8.3lf ",a[i][j]);
          printf("\n");
       }
       printf("\n");   
    }
    
    //______________________________________________________________________________
    void printMatrixE(double** a, int rows, int cols)
    {
        int i, j;
       printf("Matrix[%d][%d]\n",rows,cols);    
       for(i=0;i<rows;i++){
          for(j=0;j<cols;j++)
          printf("%9.2e ",a[i][j]);
          printf("\n");
       } 
       printf("\n");     
    }
    
    
    //______________________________________________________________________________
    
    void multMatrixp(double **A, double **B, double **C,int ro1,int co1,int ro2,int co2)
    {
        int i, j, k;
        for(i = 0; i < ro1; i++) {
            for(j = 0; j < co2; j++) {
                C[i][j] = 0;
                for(k = 0; k < co1; k++) {
                    C[i][j] += A[i][k] * B[k][j];
                }
            }
        }
    }
    
    //______________________________________________________________________________
    
    void multMatrixpp(double **A, double **B, double ***C,int ro1,int co1,int ro2,int co2)
    {
        int i, j, k;
    *C= (double**) malloc(ro1*sizeof(double*));
    for(i=0;i<ro1;i++)
    (*C)[i]=(double*)malloc(co2*sizeof(double));
    
        for(i = 0; i < ro1; i++) {
            for(j = 0; j < co2; j++) {
                (*C)[i][j] = 0.0;
                for(k = 0; k < co1; k++) {
                    (*C)[i][j] += A[i][k] * B[k][j];
                }
            }
        }
    }
    
    
    //______________________________________________________________________________
    
    double** multMatrixpf(double **A, double **B, int ro1,int co1,int ro2,int co2)
    {
        int i, j, k;
        double **C;
    C= (double**) malloc(ro1*sizeof(double*));
    for(i=0;i<ro1;i++)
    C[i]=(double*)malloc(co2*sizeof(double));
    
        for(i = 0; i < ro1; i++) {
            for(j = 0; j < co2; j++) {
                C[i][j] = 0.0;
                for(k = 0; k < co1; k++) {
                    C[i][j] += A[i][k] * B[k][j];
                }
            }
        }
         return C;              
    }
    

    作为输入矩阵,我们有 in.txt

    4 4
    1 1 1 1
    2 4 8 16
    3 9 27 81
    4 16 64 256
    4 3
    4.0 -3.0 4.0
    -13.0 19.0 -7.0
    3.0 -2.0 7.0
    -1.0 1.0 -1.0
    3 4
    1 2 -2 0
    -3 4 7 2
    6 0 3 1
    4 2
    -1 3
    0 9
    1 -11
    4 -5
    

    在 unix 之类的 cmmd 行中执行命令:

    $ 时间./Matmult out.txt

    然后你得到输出

    out.txt

    Ex1:____________________________________________________________________________ 
    Matrix[2][3]
       1.000    3.000    5.000 
       2.000    4.000    0.000 
    
    Matrix[3][4]
       6.000    2.000    4.000    8.000 
       1.000    7.000    0.000    9.000 
       0.000    3.000    5.000    1.000 
    
    MatMult 
    Matrix[2][4]
       9.000   38.000   29.000   40.000 
      16.000   32.000    8.000   52.000 
    
    Matrix[2][4]
     9.00e+00  3.80e+01  2.90e+01  4.00e+01 
     1.60e+01  3.20e+01  8.00e+00  5.20e+01 
    
    Ex2:____________________________________________________________________________ 
    Matrix[4][4]
       1.000    1.000    1.000    1.000 
       2.000    4.000    8.000   16.000 
       3.000    9.000   27.000   81.000 
       4.000   16.000   64.000  256.000 
    
    Matrix[4][3]
       4.000   -3.000    4.000 
     -13.000   19.000   -7.000 
       3.000   -2.000    7.000 
      -1.000    1.000   -1.000 
    
    MatMult 
    Matrix[4][3]
      -7.000   15.000    3.000 
     -36.000   70.000   20.000 
    -105.000  189.000   57.000 
    -256.000  420.000   96.000 
    
    Matrix[4][3]
    -7.00e+00  1.50e+01  3.00e+00 
    -3.60e+01  7.00e+01  2.00e+01 
    -1.05e+02  1.89e+02  5.70e+01 
    -2.56e+02  4.20e+02  9.60e+01 
    
    Ex3:____________________________________________________________________________ 
    Matrix[3][4]
       1.000    2.000   -2.000    0.000 
      -3.000    4.000    7.000    2.000 
       6.000    0.000    3.000    1.000 
    
    Matrix[4][2]
      -1.000    3.000 
       0.000    9.000 
       1.000  -11.000 
       4.000   -5.000 
    
    MatMult 
    Matrix[3][2]
      -3.000   43.000 
      18.000  -60.000 
       1.000  -20.000 
    
    Matrix[3][2]
    -3.00e+00  4.30e+01 
     1.80e+01 -6.00e+01 
     1.00e+00 -2.00e+01 
    

    【讨论】:

      【解决方案3】:

      这是任何有效矩阵乘法的代码...... 随意“查询”....

      #include<stdio.h>
      #include<conio.h>
      #include<stdlib.h>
      
      int main()
      {
      
              int *ans,*first,*second;
              int *A,*B,*C;
              int i,j,k=0;
              int rowA,colA,sizeA,sizeB,sizeC;
              int rowB,colB;
      
              printf("Enter the row's and column of 1st matrix\n");
              scanf("%d%d",&rowA,&colA);
      
      
              printf("Enter the row's and column of 2nd matrix\n");
              scanf("%d%d",&rowB,&colB);
      
              if(colA!=rowB)
              {
                  printf("Error => colA must be equal to rowB\n");
                  getch();
                  exit(EXIT_SUCCESS);
              }
      
      
              sizeC = rowA*colB;
              sizeA = rowA*colA;
              sizeB = rowB*colB;
      
              A  = (int *)malloc(sizeA*sizeof(int *));
              first = A;
      
              B = (int *)malloc(sizeB*sizeof(int *));
              second = B;
      
              C    = (int *)malloc(sizeC*sizeof(int *));
              ans = C;
      
      
              printf("Enter the elements of the first matrix A\n");
      
              for(i=0;i<sizeA;i++,first++)
              scanf("%d",first);
      
              printf("Enter the elements of the second matrix B\n");
      
              for(i=0;i<sizeB;i++,second++)
              scanf("%d",second);
      
              first=A;        
              second= B;      
      
              if(rowA==1 && colB==1)
              {
                  for(i=0;i<rowA;i++)
                  {
                      for(j=0;j<colB;j++)
                      {
                      *ans=0;
                      for(k=0;k<rowB;k++)
                          *ans = *ans + (*(first + (k + i*colA))) * (*(second + (j+k*colB)));
                      ans++;
                      }//j
                  }//i
              }//if
      
          else
          {
              for(i=0;i<rowA;i++)
              {
              for(j=0;j<colB;j++)
              {
                  *ans=0;
                  for(k=0;k<rowB;k++)
                      *ans = *ans + (*(first + (k + i*colA))) * (*(second + (j+k*rowB)));
                  ans++;
              }//j
              }//i
      
              }
      
              printf("\nThe value of matrix 'C' = \n");
      
              ans = C;
      
              for(i=0;i<rowA;i++)
              {
               printf("\n");
               for(j=0;j<colB;j++,ans++)
               printf("%d\t",*ans);
               }
      
              free(A);
              free(B);
              free(C);
              getch();
          }
      

      【讨论】:

        【解决方案4】:
        mat1= (int**) malloc(r1*sizeof(int*));
        
        for(i=0;i<c1;i++)  < c1 instead of r1
            mat1[i]=(int*)malloc(c1*sizeof(int));
        
        mat2= (int**) malloc(r2*sizeof(int*));
        
        for(i=0;i<c2;i++)   < c2 instead of r2
            mat2[i]=(int*)malloc(c2*sizeof(int));
        

        您在 for 中使用 c1/2 而不是 r1/2。

        如果 r1

        如果 r1 > c1,你会得到未初始化的指针。

        与问题无关,但你应该写int main()而不是main(),第二个被接受但第一个更容易阅读。

        【讨论】:

        • 太棒了!尝试使用更长的变量名,更详细地描述变量的用途,它可以防止这个错误:)
        猜你喜欢
        • 1970-01-01
        • 2021-10-28
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        • 2011-10-15
        • 1970-01-01
        • 2021-12-19
        • 1970-01-01
        相关资源
        最近更新 更多