矩阵乘法适用于具有动态内存分配的任何正确顺序

时间:2014-03-27 14:22:31

标签: c matrix dynamic-memory-allocation

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

请小心地告诉我,如果我犯了一些愚蠢的错误,请原谅我......

以下是完整的代码:

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

4 个答案:

答案 0 :(得分:2)

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而不是r1 / 2中使用c1 / 2.

如果r1&lt; c1,你最终在你分配的内存之外。

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

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

答案 1 :(得分:1)

这是任何有效矩阵乘法的代码.... 对“查询”感到自由....

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

答案 2 :(得分:0)

我附上了Matrix Multiplication的代码,用于动态内存分配的任何正确顺序

为了完整性,我使用了3种不同的矩阵乘法方法:一个函数double** multMatrixpf(参见等效函数Fortran / Pascal)和两个子程序/过程(Fortran / Pascal之类),其中首先是void multMatrixp你需要allocate_mem(&c,ro1,co2)外部和第二个子程序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行执行命令:

$ time ./Matmult&lt; in.txt&gt; 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 :(得分:0)

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