# Problem with 'Matrix Multiplication using Pointers'

This is a discussion on Problem with 'Matrix Multiplication using Pointers' within the C Programming forums, part of the General Programming Boards category; Hello C Gurus, I am writing a C prog for Matrix Multiplication of X rows and Y cols using Pointers ...

1. ## Problem with 'Matrix Multiplication using Pointers'

Hello C Gurus,

I am writing a C prog for Matrix Multiplication of X rows and Y cols using Pointers but getting warning and error:

Warning : Suspicious pointer conversion
Error : Illegal use of pointer // in multiplication func

Not sure what I am missing?

2. Here is the code :

Code:
```  #include<stdio.h>
#include<conio.h>

void input(int**x,int*p1,int*p2) //accepting matix from user
{
register int i,j,f;
do
{
f=0;
printf("\nenter no. of rows matrix[<=10]::");//no. of rows & validation
scanf("%d",p1);
if(*p1>0&&*p1<=10)
f=0;
else
{
printf("/ninvalid input");
f=1;
}
}
while(f==1);
do
{
f=0;
printf("\nenter no. of colomns for matrix[<=10]::");//no of cloumns &validation for it
scanf("%d",p2);
if(*p2>0&&*p2<=10)
f=0;
else
{
printf("/ninvalid input");
f=1;
}
}while(f==1);

for(i=0;i<*p1;i++)
{
for(j=0;j<*p2;j++)
{
printf("enter element in %d row and %d coloumn::",i+1,j+1);
scanf("%d",(*(x+i)+j));
}
}
}

void display(int **x,int *p1,int *p2)//printing matrix
{
register int i,j;
for(i=0;i<*p1;i++)
{
for(j=0;j<*p2;j++)
{
printf("   %d  ",(*(*(x+i)+j)));
}
printf("\n");
}
}

{
register  int i,j;
int **c;
for(i=0;i<*p1;i++)
{
for(j=0;j<*p2;j++)
{
(*(*(c+i)+j))=(*(*(x+i)+j))+(*(*(y+i)+j));
}
}
display(c,p1,p2);
}

void subs(int**a,int**b,int*p1,int*p2)//substrction of matrix
{
register int i,j;
int **d;
for(i=0;i<*p1;i++)
{
for(j=0;j<*p2;j++)
{
(*(*(d+i)+j))=(*(*(a+i)+j))+(*(*(b+i)+j));
}
}
display(d,p1,p2);
}

void mul(int **x,int**y,int **e,int*p1,int*p2,int*p3)//multiplication
{
register int i,j,k;
int sum;

for(i=0;i<*p1;i++)
{
for(j=0;j<*p2;j++)
{
sum=0;
for(k=0;k<*p3;k++)
{
sum=sum+((*(*(x+i)+k))*(*(*(y+k)+j)));
}
*(*(e+i)+k)=sum;
}
}
}

int min(int*a,int *p1) //finding minimum from array
{
int temp,i,j;
for(i=0;i<*p1;i++)
{
for(j=0;j<*p1;j++)
{
if((*(a+i))<(*(a+j)))
{
temp=(*(a+i));
(*(a+i))=(*(a+j));
(*(a+j))=temp;
}
}
}
return a[0];
}

int max(int *a,int*p1)//finding maximum of array
{
int temp,i,j;
for(i=0;i<*p1;i++)
{
for(j=0;j<*p1;j++)
{
if((*(a+i))>(*(a+j)))
{
temp=(*(a+i));
(*(a+i))=(*(a+j));
(*(a+j))=temp;
}
}
}
return a[0];
}

{
int i,j,row[10],col[10],temp1[10],temp2[10],y,z;

for(i=0;i<*m;i++)
{
for(j=0;j<*n;j++)
{
*(row+j)=(*(*(c+i)+j));
*(col+j)=(*(*(c+j)+i));
}
*(temp1+i)=max(row,&n);
*(temp2+i)=min(col,&m);
}
y=min(temp1,&m);
z=max(temp2,&n);

if(y==z)
printf("  %d",y);
else
}
void trans(int**x,int*m,int*n)//printing transpose
{
int i,j;
int y[10][10];
for(i=0;i<*m;i++)
{
for (j=0;j<*n;j++)
{
*(*(y+j)+i)=*(*(x+i)+j);
}
}
display(y,n,m);
}

void main()
{
int a[10][10],b[10][10],c[10][10]; //intialisation
void input(int**,int*,int*);    //user defined functions
void display(int**,int*,int*);
void subs(int**,int**,int*,int*);
void mul(int**,int**,int**,int*,int*,int*);
int min(int*,int*);
int max(int*,int*);
void trans(int**,int*,int*);
int ch,m,n,m1,n1,flg,**ptr1,**ptr2;
char s;
do
{
clrscr();
printf("\n\n matrix A\n");
input(a,&m,&n);
display(a,&m,&n);
printf("\n\n matrix B\n");
input(b,&m1,&n1);
display(b,&m1,&n1);

flg=0;
clrscr();
printf("\n\n matrix A\n");
display(a,&m,&n);
printf("\n\n matrix B\n");
display(b,&m1,&n1);
printf("\n\nwhich matrix operation want to perform\n\t 1::Addition of matrix\n\t 2::Substraction of matrix\n\t 3::Multiplication of matrix\n\t 4::Find saddle point\n\t 5::Transpose\n\t 6::Exit\n\n Enter choice!!!");
scanf("%d",&ch);

switch(ch)          //taking choice
{
case 1: if(m==m1&&n==n1)
{
printf("\n\t addition of given matrices is=\n");
}
else
{
}
break;

case 2:if(m==m1&&n==n1)
{
printf("\n\t substraction of given matrices is=\n");
subs(a,b,&m,&n);
}
else
{
printf("\n\tsubstraction not possible");
}
break;
case 3:if(n==m1)
{
printf("\n\t multiplication of given matrix is=\n");
mul(a,b,c,&m,&n,&n1);
display(c,&m,&n1);
}

else
{
printf("\n\tmultiplication not possible");
}
break;
case 4: printf("\n\tsaddle point in matrix A is=");

printf("\n\n\t sadddle point in matrix B is=");

break;
case 5: printf(" trnaspose of matrices are");
printf("\n\n matrix A\n");
trans(a,&m,&n);
printf("\n\n matrix B\n");
trans(b,&m1,&n1);
break;

case 6: printf("do u want to exit?(y/n)");
scanf(" %c",&s);
break;
default: printf("enter valid choice");

}
getch();

if(s=='y')
flg=0;
else
flg=1;
}
while(flg==1);
getch();
}```

3. Try expressing the function in terms of arrays. If you can't do that, you will have no hope of doing the same thing using pointers.

4. Thanks grumpy.
Sorry Im bit new in C, im not sure what you mean exactly? Can you please paste sample?

5. Some of the regular tips we give people that apply to you:
• Don't use the 'register' keyword. At best it's just a gimmick for noobs nowdays, and using it is not actually beneficial.
• a[b] and *(a + b) are the same. Use the syntax that is cleaner.
• main should return int, not void.
• Don't delete parameter names from function prototypes, and preferably don't put them inside functions.
• A little whitespace never hurt anyone:
Code:
`if (*p1 > 0 && *p1 <= 10)`

Also, using f or flg as a "flag" isn't very meaningful, nor is assigning integer values and declaring it as an int. The name of the variable should tell you what it is used for, and you should use the typical typedef for a boolean and defines for TRUE and FALSE. Preferably it would be switched around to be worded in a positive manner too, to avoid double-negatives. E.g.
Code:
```BOOL inputIsValid;
inputIsValid = TRUE;```

6. Thanks for the info.

7. All your function prototypes and declarations are wrong.

To pass these arrays to a function,
int a[10][10],b[10][10],c[10][10]; //intialisation

You need to declare the array parameter as
void input(int[][10],int*,int*); //user defined functions

The "arrays-become-pointers" rule is NOT recursive - it applies only to the left-most dimension of an array.
Strictly speaking, the parameter type in the function should be int (*)[10] (a pointer to an array of 10 int's).
But for ease of typing, the int[][10] notation works just as well.

Why you shouldn't write 100's of lines of code and then post "it doesn't work"
A development process
You should have made sure that say "input" and "print" worked before charging ahead with the same mistakes in all the add/sub/mul/.... functions.

8. Originally Posted by JennyG
Easy: Start from scratch.

After removing the non-standard getch()- and clrscr()-functions, I still get 57(!) lines of warning messages:
Code:
```\$ gcc -g -Wall -Wextra -o test test.c
test.c:153:7: warning: passing argument 2 of ‘max’ from incompatible pointer type [enabled by default]
test.c:122:6: note: expected ‘int *’ but argument is of type ‘int **’
test.c:154:7: warning: passing argument 2 of ‘min’ from incompatible pointer type [enabled by default]
test.c:104:5: note: expected ‘int *’ but argument is of type ‘int **’
test.c:156:6: warning: passing argument 2 of ‘min’ from incompatible pointer type [enabled by default]
test.c:104:5: note: expected ‘int *’ but argument is of type ‘int **’
...```
Nevertheless I've tried to start the program:
Code:
```\$ ./test

matrix A

enter no. of rows matrix[<=10]::4

enter no. of colomns for matrix[<=10]::3
enter element in 1 row and 1 coloumn::1
Segmentation fault```
It crashes even before I can choose the multiplication!

Instead of dumping a big non-working program on us, try to simplify your problem to a short example.

Bye, Andreas

9. Thanks for info again.
The code works fine on Windows for Add, Sub and everything but just not for Mul and hence need help in understanding the fix in above code.

10. Originally Posted by JennyG
The code works fine on Windows for Add, Sub and everything but just not for Mul
Rubbish. If you're telling us that the add method posted above is working, then you are horribly mistaken.
The code you're posted is writing through an uninitialised double-pointer and reading through pointers with the wrong levels of indirection. That isn't even close to something that could ever "work". On Windows it is very predictable that it will crash.
It will never work until you're fixed up the most important things that have been mentioned above.

If you have some other fixed up code that actually runs now, you should post that. We aren't going to write it for you. The more you try and apply the help given and post what you've tried, and the more you ask specific questions, the quicker you'll get to something that works.

11. Thanks guys. Sorry for my terrible mistake. I pasted wrong code above.
The proper code is here (with 0 errors and a warning 'Suspicious pointer conversion')
Code executes without an issue for all options but multiplication output is still coming up wrong.

Code:
```  void input(int(*x)[10],int*p1,int*p2) //accepting matix from user
{
register int i,j,f;
int*k;
do
{
f=0;
printf("\nenter no. of rows matrix[<=10]::");//no. of rows & validation
scanf("%d",p1);
if(*p1>0&&*p1<=10)
f=0;
else
{
printf("/ninvalid input");
f=1;
}
}
while(f==1);
do
{
f=0;
printf("\nenter no. of colomns for matrix[<=10]::");//no of cloumns &validation for it
scanf("%d",p2);
if(*p2>0&&*p2<=10)
f=0;
else
{
printf("/ninvalid input");
f=1;
}
}while(f==1);

for(i=0;i<*p1;i++)
{
k=x+i;
for(j=0;j<*p2;j++)
{
printf("enter element in %d row and %d coloumn::",i+1,j+1);
scanf("%d",(k+j));
}
}
}

void display(int(*x)[10],int *p1,int *p2)//printing matrix
{
register int i,j;
int*k;
for(i=0;i<*p1;i++)
{
k=x+i;
for(j=0;j<*p2;j++)
{
printf("   %d  ",(*(k+j)));
}
printf("\n");
}
}

{
register  int i,j;
int c[10][10],*k,*l,*p;
for(i=0;i<*p1;i++)
{
k=x+i;
l=y+i;
p=c+i;
for(j=0;j<*p2;j++)
{
(*(p+j))=(*(k+j))+(*(l+j));
}
}
display(c,p1,p2);
}

void subs(int(*x)[10],int(*y)[10],int*p1,int*p2)//substrction of matrix
{
register  int i,j;
int c[10][10],*k,*l,*p;
for(i=0;i<*p1;i++)
{
k=x+i;
l=y+i;
p=c+i;
for(j=0;j<*p2;j++)
{
(*(p+j))=(*(k+j))-(*(l+j));
}
}
display(c,p1,p2);
}

void mul(int(*x)[10],int(*y)[10],int(*e)[10],int*p1,int*p2,int*p3)//multiplication
{
register int i,j,k;
int sum,*s,*t,*r,z,h;

for(i=0;i<*p1;i++)
{
s=x+i;
r=e+i;
for(j=0;j<*p2;j++)
{
sum=0;
for(k=0;k<*p3;k++)
{
t=y+k;
z=*(s+k);
h=*(y+j);
sum=sum+(z*h);
}
*(r+k)=sum;
}
}
}

int min(int a[],int *p1) //finding minimum from array
{
int temp,i,j;
for(i=0;i<*p1;i++)
{
for(j=0;j<*p1;j++)
{
if(a[i]<a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
return a[0];
}

int max(int a[],int*p1)//finding maximum of array
{
int temp,i,j;
for(i=0;i<*p1;i++)
{
for(j=0;j<*p1;j++)
{
if(a[i]>a[j])
{
temp=a[i];
a[j]=a[j];
a[j]=temp;
}
}
}
return a[0];
}

{
int i,j,row[10],col[10],temp1[10],temp2[10],y,z,*p,*q;

for(i=0;i<*m;i++)
{
p=c+i;
for(j=0;j<*n;j++)
{
q=c+j;
*(row+j)=*(p+j);
*(col+j)=*(q+i);
}
*(temp1+i)=max(row,n);
*(temp2+i)=min(col,m);

}
y=min(temp1,m);
z=max(temp2,n);

if(y==z)
printf("  %d",y);
else
}

void trans(int(*x)[10],int*m,int*n)//printing transpose
{
int i,j,*p,*q;
int y[10][10];
for(i=0;i<*m;i++)
{
p=x+i;
for (j=0;j<*n;j++)
{
q=y+j;
*(q+i)=*(p+j);
}
}
display(y,n,m);
}

void main()
{
int a[10][10],b[10][10],c[10][10]; //intialisation
void input(int(*)[],int*,int*);    //user defined functions
void display(int(*)[],int*,int*);
void subs(int(*)[],int(*)[],int*,int*);
void mul(int(*)[],int(*)[],int(*)[],int*,int*,int*);
int min(int[],int*);
int max(int[],int*);
void trans(int(*)[],int*,int*);
int ch,m,n,m1,n1,flg;
char s;
do
{
clrscr();
printf("\n\n matrix A\n");
input(a,&m,&n);
display(a,&m,&n);
printf("\n\n matrix B\n");
input(b,&m1,&n1);
display(b,&m1,&n1);

flg=0;
clrscr();
printf("\n\n matrix A\n");
display(a,&m,&n);
printf("\n\n matrix B\n");
display(b,&m1,&n1);
printf("\n\nwhich matrix operation want to perform\n\t 1::Addition of matrix\n\t 2::Substraction of matrix\n\t 3::Multiplication of matrix\n\t 4::Find saddle point\n\t 5::Transpose\n\t 6::Exit\n\n Enter choice!!!");
scanf("%d",&ch);

switch(ch)          //taking choice
{
case 1: if(m==m1&&n==n1)
{
printf("\n\t addition of given matrices is=\n");
}
else
{
}
break;

case 2:if(m==m1&&n==n1)
{
printf("\n\t substraction of given matrices is=\n");
subs(a,b,&m,&n);
}
else
{
printf("\n\tsubstraction not possible");
}
break;
case 3:if(n==m1)
{
printf("\n\t multiplication of given matrix is=\n");
mul(a,b,c,&m,&n,&n1);
display(c,&m,&n1);
}

else
{
printf("\n\tmultiplication not possible");
}
break;
case 4: printf("\n\tsaddle point in matrix A is=");

printf("\n\n\t sadddle point in matrix B is=");

break;
case 5: printf(" trnaspose of matrices are");
printf("\n\n matrix A\n");
trans(a,&m,&n);
printf("\n\n matrix B\n");
trans(b,&m1,&n1);
break;

case 6: printf("do u want to exit?(y/n)");
scanf(" %c",&s);
break;
default: printf("enter valid choice");

}
getch();

if(s=='y')
flg=0;
else
flg=1;
}
while(flg==1);
getch();
}```

12. You get only one warning from all of that? Do you have compiler warnings suppressed or something? I get 27 warnings at the default warning level and 33 with all warnings enabled.

Most of the warnings are of this form:
Code:
`warning: assignment from incompatible pointer type`
It appears to have all or most of the same issues as others have mentioned already.

13. After #including conio.h and commenting out the clrscr calls, I get 30 errors. Not just warnings that let you mistakenly produce a program that may not behave correctly, but actual errors. The compiler outright refuses to produce any code at all. Errors such as:
Code:
```error C2440: '=' : cannot convert from 'int (*)[10]' to 'int *'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast```
These errors suggest that one can force the compiler to accept the nonsense it is given by giving it a brutal cast.

Plus where you aparently get a warning, I get an even worse error:
Code:
```error C2440: '=' : cannot convert from 'int [10]' to 'int'
1>        There is no context in which this conversion is possible```
This one is even worse, and I'm surprised that any kind of cast can manage to force the compiler to take it.

A compiler that blatently accepts the badly wrong code you are giving it here without so much as a warning, is not a good learning tool. It is not advising you of your mistakes, so you are not able to learn from them. I fear you must be using that Turbid Crap++ or something nearly as awful.
If ever there was a time where one should follow the advice of changing to a better compiler, this would be it. You wouldn't ask a drunk and high guy with violent tendencies and flamethrower to teach you rocket science. So don't ask a dead beat useless as <insert colourful word here> compiler to teach you how to program.

Also, when you want help, ignoring suggestions is one of the worst things you can do. If you don't understand the advice given then you should either query it, or say why you are plan to do nothing in regards to it.

14. Thanks all of you. code updated and now works for all cases (on windows - TC)
However im still unable to remove 15 warnings for 'Suspicious pointer conversion'
Can you try to run this code on your system?

Code:
``` void input(int(*x)[10],int*p1,int*p2) //accepting matix from user
{
register int i,j,f;
int*k;
do
{
f=0;
printf("\nenter no. of rows matrix[<=10]::");//no. of rows & validation
scanf("%d",p1);
if(*p1>0&&*p1<=10)
f=0;
else
{
printf("/ninvalid input");
f=1;
}
}
while(f==1);

do
{
f=0;
printf("\nenter no. of colomns for matrix[<=10]::");//no of cloumns &validation for it
scanf("%d",p2);
if(*p2>0&&*p2<=10)
f=0;
else

{
printf("/ninvalid input");
f=1;
}
}
while(f==1);

for(i=0;i<*p1;i++)
{
k=x+i;
for(j=0;j<*p2;j++)
{
printf("enter element in %d row and %d coloumn::",i+1,j+1);
scanf("%d",(k+j));
}
}
}

void display(int(*x)[10],int *p1,int *p2)//printing matrix
{
register int i,j;
int*k;
for(i=0;i<*p1;i++)
{
k=x+i;
for(j=0;j<*p2;j++)
{
printf("\t%d",(*(k+j)));
}
printf("\n");
}
}

{
register  int i,j;
int c[10][10],*k,*l,*p;
for(i=0;i<*p1;i++)
{
k=x+i;
l=y+i;
p=c+i;
for(j=0;j<*p2;j++)
{
(*(p+j))=(*(k+j))+(*(l+j));
}
}
display(c,p1,p2);
}

void subs(int(*x)[10],int(*y)[10],int*p1,int*p2)//substrction of matrix
{
register  int i,j;
int c[10][10],*k,*l,*p;
for(i=0;i<*p1;i++)
{
k=x+i;
l=y+i;
p=c+i;
for(j=0;j<*p2;j++)
{
(*(p+j))=(*(k+j))-(*(l+j));
}
}
display(c,p1,p2);
}

void mul(int(*x)[10],int(*y)[10],int*m,int*n,int*n1)//multiplication
{
register int i,j,k;
int sum,e[10][10],*ip,*jp,*kp;

for(i=0;i<*m;i++)
{
ip=x+i;
jp=e+i;
for(j=0;j<*n;j++)
{
sum=0;
for(k=0;k<*n1;k++)
{
kp=(y+k);
sum=sum+(*(ip+k))*(*(kp+j));
}
(*(jp+j))=sum;
}
}
display(e,m,n1);
}

int min(int a[],int *p1) //finding minimum from array
{
int temp,i,j;
for(i=0;i<*p1;i++)
{
for(j=0;j<*p1;j++)
{
if(a[i]<a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
return a[0];
}

int max(int a[],int*p1)//finding maximum of array
{
int temp,i,j;
for(i=0;i<*p1;i++)
{
for(j=0;j<*p1;j++)
{
if(a[i]>a[j])
{
temp=a[i];
a[j]=a[j];
a[j]=temp;
}
}
}
return a[0];
}

{
int i,j,row[10],col[10],temp1[10],temp2[10],y,z,*p,*q;

for(i=0;i<*m;i++)
{
p=c+i;
for(j=0;j<*n;j++)
{
q=c+j;
*(row+j)=*(p+j);
*(col+j)=*(q+i);
}
*(temp1+i)=max(row,n);
*(temp2+i)=min(col,m);

}
y=min(temp1,m);
z=max(temp2,n);

if(y==z)
printf(" %d",y);
else
}

void trans(int(*x)[10],int*m,int*n)//printing transpose
{
int i,j,*p,*q;
int y[10][10];
for(i=0;i<*m;i++)
{
p=x+i;
for (j=0;j<*n;j++)
{
q=y+j;
*(q+i)=*(p+j);
}
}
display(y,n,m);
}

void main()
{
int a[10][10],b[10][10]; //intialisation
void input(int(*)[],int*,int*);    //user defined functions
void display(int(*)[],int*,int*);
void subs(int(*)[],int(*)[],int*,int*);
void mul(int(*)[],int(*)[],int*,int*,int*);
int min(int[],int*);
int max(int[],int*);
void trans(int(*)[],int*,int*);
int ch,m,n,m1,n1,flg;
char s;

clrscr();
printf("\n\n matrix A\n");
input(a,&m,&n);
display(a,&m,&n);
printf("\n\n matrix B\n");
input(b,&m1,&n1);
display(b,&m1,&n1);
do
{
flg=0;
clrscr();
printf("\n\n matrix A\n");
display(a,&m,&n);
printf("\n\n matrix B\n");
display(b,&m1,&n1);
printf("\n\nwhich matrix operation want to perform\n\t 1::Addition of matrix\n\t 2::Substraction of matrix\n\t 3::Multiplication of matrix\n\t 4::Find saddle point\n\t 5::Transpose\n\t 6::Exit\n\n Enter choice!!!");
scanf("%d",&ch);

switch(ch)          //taking choice
{
case 1: if(m==m1&&n==n1)
{
printf("\n\t addition of given matrices is=\n");
}
else
{
}
break;

case 2:if(m==m1&&n==n1)
{
printf("\n\t substraction of given matrices is=\n");
subs(a,b,&m,&n);
}
else
{
printf("\n\tsubstraction not possible");
}
break;
case 3:if(n==m1)
{
printf("\n\t multiplication of given matrix is=\n");
mul(a,b,&m,&n,&n1);
}

else
{
printf("\n\tmultiplication not possible");
}
break;
case 4: printf("\n\tsaddle point in matrix A is=");

printf("\n\n\t sadddle point in matrix B is=");

break;
case 5: printf(" trnaspose of matrices are");
printf("\n\n matrix A\n");
trans(a,&m,&n);
printf("\n\n matrix B\n");
trans(b,&m1,&n1);
break;

case 6: printf("do u want to exit?(y/n)");
scanf(" %c",&s);
break;
default: printf("enter valid choice");

}
getch();

if(s=='y')
flg=0;
else
flg=1;
}
while(flg==1);
getch();
}```

15. it is always the same mistake
you are adding an offset to an int(*x)[10] and expect the result to be a ponter to int -->> that is suspicious.

do as salem has told you
Code:
```void display(int(*x)[10],int *p1,int *p2)//printing matrix
{
register int i,j;
int*k;
for(i=0;i<*p1;i++)
{
// k=x+i;   <<-- wrong
k=x[i];   // <<-- right
for(j=0;j<*p2;j++)
{
printf("\t%d",(*(k+j)));
}
printf("\n");
}
}```
Kurt

Page 1 of 2 12 Last