ArasChang
ArasChang

Reputation: 1

Matrix Multiplication Using double pointers passing into functions in C

I am wondering why I cannot get the value in the function, it always cause segmentation fault... `

void multiply(int M, int N, int K, int **matrixA, int **matrixB, int **matrixC){
    for (int i = 0; i < M; i++){
        for (int j = 0; j < K; j++){
            int sum = 0;
            for (int k = 0; k < N; k++){
                sum += (*(*(matrixA + j) + k)) * (*(*(matrixB + k) + j));
            }
            *(*(matrixC + i) + j) = sum;
        }
    }
    
}

int main(){
    int M, N, K;
    scanf("%d%d%d", &M, &N, &K);
    int matrixA[M][N];
    int matrixB[N][K];
    int matrixC[M][K];
    for(int i=0; i<M; i++){
        for(int j=0; j<N; j++){
            scanf("%d", matrixA[i]+j);
        }
    }

    for(int i=0; i<N; i++){
        for(int j=0; j<K; j++){
            scanf("%d", matrixB[i]+j);
        }
    }

    multiply(M, N, K, (int **)matrixA, (int **)matrixB, (int **)matrixC);
    for(int i=0; i<M; i++){
        for(int j=0; j<K; j++){
            printf("%d ", matrixC[i][j]);
        }
        printf("\n");
    }
    return 0;
}

`

I want to print out the result "matrixC", but in the function, it would cause segmentation fault. I have tried several times, and it seems like it would miss the addresses of the pointer under the double pointers.

Upvotes: 0

Views: 248

Answers (1)

Change the prototype of the function multiply to this:

void multiply(int M, int N, int K, int matrixA[M][N], int matrixB[N][K], int matrixC[M][K]);

make your life easier like this (body of function multiply):

for (int i = 0; i < M; i++) { //for each row of matrixA
    for (int j = 0; j < K; j++) { //for each column of matrixB
        matrixC[i][j] = 0; //set field to zero
        for (int k = 0; k < N; k++) { //for each col of A and each row of B
            //take the dot product of row i (matrixA) and col j (matrixB)
            matrixC[i][j] += matrixA[i][k] * matrixB[k][j];
        }
    }
}

You have an error in this line

sum += (*(*(matrixA + j) + k)) * (*(*(matrixB + k) + j));

which has been corrected to

matrixA[i][k] //index 'i' not 'j'

The var sum is not needed, therefore opted out.


Based on your comment below

Consider the following code:

int arr[2][2];
int n=0;

for (int i=0; i < 2; ++i) {
    for (int j=0; j < 2; ++j) {
        arr[i][j] = ++n;
        printf("%p (%d)  ", &arr[i][j], arr[i][j]);
    }
    printf("\n");
}

Possible output:

0x7fff7c729470 (1)  0x7fff7c729474 (2)  
0x7fff7c729478 (3)  0x7fff7c72947c (4)

As you can see, nicely packed into consecutive integers (basically one array of ints - but that is not guaranteed).

Now have a look at this:

int **parr = (int**) arr;

for (int i=0; i < 2; ++i) {
    for (int j=0; j < 2; ++j) {
        printf("%p ", *(parr + i) + j);
    }
    printf("\n");
}

Possible output:

0x200000001 0x200000005 
0x400000003 0x400000007

Now, that looks (dangerously) ugly.


As always: pointer != array. Pointer to pointer means, an address of another address, whereas an array is a consecutive block of a type (you could for example take the address of the first element, which is done if the array decays to a pointer).

You have to give the compiler enough information, e.g.

int (*parr)[2] = arr;

See also: https://en.cppreference.com/w/c/language/array#Multidimensional_arrays

Upvotes: 1

Related Questions