Reputation: 115
I have a task where I'm supposed to multiply two quadratic matrices of size n
in C, using pointers as function parameters and return value. This is the given function head: int** multiply(int** a, int** b, int n)
. Normally, I would use three arrays (the two matrices and the result) as parameters, but since I had to do it this way, this is what I came up with:
#include <stdio.h>
#include <stdlib.h>
int** multiply(int** a, int** b, int n) {
int **c = malloc(sizeof(int) * n * n);
// Rows of c
for (int i = 0; i < n; i++) {
// Columns of c
for (int j = 0; j < n; j++) {
// c[i][j] = Row of a * Column of b
for (int k = 0; i < n; k++) {
*(*(c + i) + j) += *(*(a + i) + k) * *(*(b + k) + j);
}
}
}
return c;
}
int main() {
int **a = malloc(sizeof(int) * 2 * 2);
int **b = malloc(sizeof(int) * 2 * 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; i < 2; j++) {
*(*(a + i) + j) = i - j;
*(*(b + i) + j) = j - i;
}
}
int **c = multiply(a, b, 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("c[%d][%d] = %d\n", i, j, c[i][j]);
}
}
free(a);
free(b);
free(c);
return 0;
}
I have not worked much with pointers before, and am generally new to C, so I have no idea why this doesn't work or what I'd have to do instead. The error I'm getting when trying to run this program is segmentation fault (core dumped)
. I don't even know exactly what that means... :(
Can someone please help me out?
Upvotes: 1
Views: 608
Reputation: 17403
From the updated requirement, the actual function prototype is int *multiply(int *a, int *b, int n);
so the code should use a "flattened" matrix representation consisting of a 1-D array of length n * n
.
Using a flattened representation, element (i
, j
) of the n * n
matrix m
is accessed as m[i * n + j]
or equivalently using the unary *
operator as *(m + i * n + j)
. (I think the array indexing operators are more readable.)
First, let us fix some errors in the for
loop variables. In multiply
:
for (int k = 0; i < n; k++) {
should be:
for (int k = 0; k < n; k++) {
In main
:
for (int j = 0; i < 2; j++) {
should be:
for (int j = 0; j < 2; j++) {
The original code has a loop that sums the terms for each element of the resulting matrix c
, but is missing the initialization of the element to 0 before the summation.
Corrected code, using the updated prototype with flattened matrix representation:
#include <stdio.h>
#include <stdlib.h>
int* multiply(int* a, int* b, int n) {
int *c = malloc(sizeof(int) * n * n);
// Rows of c
for (int i = 0; i < n; i++) {
// Columns of c
for (int j = 0; j < n; j++) {
// c[i][j] = Row of a * Column of b
c[i * n + j] = 0;
for (int k = 0; k < n; k++) {
c[i * n + j] += a[i * n + k] * b[k * n + j];
}
}
}
return c;
}
int main() {
int *a = malloc(sizeof(int) * 2 * 2);
int *b = malloc(sizeof(int) * 2 * 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
a[i * 2 + j] = i - j;
b[i * 2 + j] = j - i;
}
}
int *c = multiply(a, b, 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("c[%d][%d] = %d\n", i, j, c[i * 2 + j]);
}
}
free(a);
free(b);
free(c);
return 0;
}
Upvotes: 1
Reputation: 213862
There's lots of fundamental problems in the code. Most notably, int**
is not a 2D array and cannot point at one.
i<2
typo in the for(int j...
loop.i < n
in the for(int k...
loop.int (*a)[2] = malloc(sizeof(int) * 2 * 2);
. Or if you will malloc( sizeof(int[2][2]) )
, same thing.a[i][j]
.void func (int n, int arr[n][n]);
void*
and get that working.malloc
doesn't initialize the allocated memory. If you want to do +=
on c
you should use calloc
instead, to set everything to zero.*(*(c + i) + j)
. Write c[i][j]
.I fixed these problems and got something that runs. You check if the algorithm is correct from there.
#include <stdio.h>
#include <stdlib.h>
void* multiply(int n, int a[n][n], int b[n][n]) {
int (*c)[n] = calloc(1, sizeof(int[n][n]));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
return c;
}
int main() {
int (*a)[2] = malloc(sizeof(int[2][2]));
int (*b)[2] = malloc(sizeof(int[2][2]));
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
a[i][j] = i - j;
b[i][j] = j - i;
}
}
int (*c)[2] = multiply(2, a, b);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("c[%d][%d] = %d\n", i, j, c[i][j]);
}
}
free(a);
free(b);
free(c);
return 0;
}
Upvotes: 4
Reputation: 139
You need to fix multiple errors here:
1/ line 5/24/28: int **c = malloc(sizeof(int*) * n )
2/ line 15: k<n
3/ Remark: use a[i][j]
instead of *(*(a+i)+j)
4/ line 34: j<2
5/ check how to create a 2d matrix using pointers.
#include <stdio.h>
#include <stdlib.h>
int** multiply(int** a, int** b, int n) {
int **c = malloc(sizeof(int*) * n );
for (int i=0;i<n;i++){
c[i]=malloc(sizeof(int) * n );
}
// Rows of c
for (int i = 0; i < n; i++) {
// Columns of c
for (int j = 0; j < n; j++) {
// c[i][j] = Row of a * Column of b
for (int k = 0; k < n; k++) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
return c;
}
int main() {
int **a = malloc(sizeof(int*) * 2);
for (int i=0;i<2;i++){
a[i]=malloc(sizeof(int)*2);
}
int **b = malloc(sizeof(int) * 2);
for (int i=0;i<2;i++){
b[i]=malloc(sizeof(int)*2);
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
a[i][j] = i - j;
b[i][j] = i - j;
}
}
int **c = multiply(a, b, 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("c[%d][%d] = %d\n", i, j, c[i][j]);
}
}
free(a);
free(b);
free(c);
return 0;
}
Upvotes: 1