C语言 具有动态内存分配的任何适当顺序的矩阵乘法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22690466/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Matrix Multiplication for any proper order with dynamic memory allocation
提问by Himanshu Sourav
I am trying to perform matrix multiplication(dynamic memory allocation) where that the user can enter any valid order for matrix multiplication (i.e. column1=row2). The output for same orders (2x2 or 3x3) for both matrices result in proper computation, but the orders like mat1 2x3 & mat2 3x2..give segmentation fault. I am not able to ascertain how am I accessing any illegal memory when I am doing the memory allocation beforehand.
我正在尝试执行矩阵乘法(动态内存分配),用户可以在其中输入任何有效的矩阵乘法顺序(即 column1=row2)。两个矩阵的相同阶数(2x2 或 3x3)的输出导致正确的计算,但是像 mat1 2x3 & mat2 3x2..g 这样的阶数会导致分段错误。当我事先进行内存分配时,我无法确定我是如何访问任何非法内存的。
kindly advise, pls forgive me if I am making some silly mistake...
恳请指教,如果我犯了一些愚蠢的错误,请原谅我...
following is the complete code:
以下是完整代码:
#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;}
回答by Taiki
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));
You use c1/2 in your forinstead of r1/2.
您使用 c1/2for而不是 r1/2。
If r1 < c1, you end up outside of the memory you allocated.
如果 r1 < c1,则最终会超出分配的内存。
If r1 > c1, you end up with uninitialized pointers.
如果 r1 > c1,您最终会得到未初始化的指针。
Not related to the issue but you should write int main()instead of main(), the second one is accepted but the first one easier to read.
与问题无关,但你应该写int main()而不是main(),第二个被接受,但第一个更容易阅读。
回答by shahrukh
Here is the code for any valid matrix multiplication.... feel free for "Queries"....
这是任何有效矩阵乘法的代码......随意“查询”......
#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();
}
回答by Andrei
I attached bellow the code for Matrix Multiplication for any proper order with dynamic memory allocation
我在下面附上了矩阵乘法的代码,用于动态内存分配的任何适当顺序
For completeness I used 3 different methods for matrix multiplication: one function double** multMatrixpf(see equivalent function Fortran/Pascal) and two subroutine/procedure(Fortran/Pascal like), where by first void multMatrixpyou need to allocate_mem(&c,ro1,co2)outside and in second subroutine void multMatrixppthe matrix c1is allocated inside the subroutine. All of these three methods give the same result.
为了完整起见,我使用了 3 种不同的矩阵乘法方法:一个函数double** multMatrixpf(参见等效函数 Fortran/Pascal)和两个子程序/过程(Fortran/Pascal 之类的),首先void multMatrixp您需要在allocate_mem(&c,ro1,co2)外部和第二个子程序中分配void multMatrixpp矩阵c1内部子程序。所有这三种方法都给出相同的结果。
As well I used different methods for initialising arrays.
我也使用了不同的方法来初始化数组。
#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;
}
where as input matrix we have in.txt
作为输入矩阵,我们有 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
in unix like cmmd line execute the command:
在像 cmmd 行的 unix 中执行命令:
$ time ./Matmult < in.txt > out.txt
$ time ./Matmult < in.txt > out.txt
and you get the output
然后你得到输出
out.txt
输出.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
回答by Aindrila Indra
While computing the matrix multiplication you have to run the k loop from 0 to c2, and not from 0 to c1.
在计算矩阵乘法时,您必须从 0 到 c2 运行 k 循环,而不是从 0 到 c1。

