2014-03-27 3 views
0

Я пытаюсь выполнить матричное умножение (распределение динамической памяти), где пользователь может ввести любой действительный порядок для умножения матрицы (т. Е. Column1 = row2). Результат для тех же заказов (2x2 или 3x3) для обеих матриц приводит к правильному вычислению, но порядки, такие как mat1 2x3 & mat2 3x2..give segmentation fault. Я не могу выяснить, как я могу получить доступ к любой незаконной памяти, когда я делаю выделение памяти заранее.Матричное умножение для любого правильного порядка с распределением динамической памяти

любезно посоветуйте, пожалуйста, прости меня, если я делаю какие-то глупые ошибки ...

Ниже приведен полный код:

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

Прошло очень много времени с тех пор, как я коснулся C. Но вы уверены, что для сканирования требуется &? они только указатели? – Ritikesh

+0

'scanf' здесь ОК. –

+0

yes Ritikesh, здесь я обращаюсь к элементам массива отдельно, поэтому мне нужно поставить & in scanf ... –

ответ

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)); 

используется c1/2 в вашем for вместо R1/2.

Если r1 < c1, вы попадаете за пределы выделенной вами памяти.

Если r1> c1, вы получите неинициализированные указатели.

Не относится к проблеме, но вы должны написать int main() вместо main(), вторая принимается, но первая легче читать.

+0

спасибо Taiki, теперь он отлично работает .. –

+1

awesome!Попробуйте использовать более длинные имена переменных, которые более подробно описывают, для чего используется переменная, это могло бы предотвратить эту ошибку :) – Taiki

0

Вот код для любого действительного матричного умножения .... чувствовать бесплатно «Запросы» ....

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

Я прикрепил ниже код для умножения матриц для любого правильного порядка с динамической памятью распределение

для полноты я использовал 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 строке выполнить команду:

$ Время ./Matmult < in.txt> 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 
Смежные вопросы