how can I get array back from function to main? I tried below program and got error as error: assignment to expression with array type

Viewed 60

I am trying to get back multiplied matrix array from pointer function to main. I am getting error as timeout: the monitored command dumped core. how to get any array return from function to main?

Here is the code:

/* multiplication of matrix in function and printing it in main */
#include <stdio.h>

int pointer(int *, int *); /* function to multiply two matrices */

int main() {
    int i, j, *a;
    int ar2[3][3];
    int ar[3][3] = {
        1, 1, 3,
        2, 1, 8,
        3, 8, 1         
    };
    int ar1[3][3] = {
        1, 1, 3,
        2, 1, 8,
        3, 8, 1          
    };
    a = pointer(ar, ar1);
    printf("asas");
    for (i = 0; i <= 2; i++) {
        for (j = 0; j <= 2; j++) {
            printf("%d   ", a[i][j]);
        }
        printf("\n");
    }            
}

int pointer(int *l, int *k) {
    int i, j, a, m = 0, *n;
    int ar[3][3];
    for (i = 0; i <= 2; i++) {
        for (j = 0; j <= 2; j++) {
            for (a = 0; a <= 2; a++) {
                m += *(l + a * 3 + j) * (*(k + a + i * 3));
            }
            ar[i][j] = m;
            m = 0;
        }
    }
    n = ar;
    return (n);
}
2 Answers

ar is allocated on function stack. When you return from the function it is already gone and it is does not exist in the main.

There are several basic ways to handle it

  1. you can make the array in the function static: static int ar[3][3];. This will make the array persistent, but every time you call the function, the same array will be changed. So, you cannot have multiple independent pointers. All will point to the same source.
  2. you can allocate array dynamically: int *arr = malloc(sizeof(int [3][3])). Now you have to makes sure that you free it in main after use. This will create independent copies of the array every time you call the function.
  3. you can allocate the array in the 'main' and pass a pointer to it to the function in order to assign values: int main(){int arr[3][3]; pointer(arr,...);} int * pointer(int *arr, ...)...
  4. you can declare your array in the global scope, visible from both, main and pointer. This is similar to #1 ...

ar is a local object in the pointer function, returning its address to the caller will invoke undefined behavior when the caller accesses it as the contents are no longer in scope and may be used for other purposes.

The array ar2 is defined in main() to receive the result and should be passed to pointer() for this purpose.

Note also that your inner loop performs the multiplication in the wrong order: matrix multiplication is not commutative, you compute k * l instead of l * k, and you would get incorrect output if the matrices in main were different.

The inner sum should be m += l[i][a] * k[a][j] instead of m += l[a][j] * k[i][a].

Here is a modified version:

void pointer(int *ar, const int *l, const int *k) {
    int i, j, a;
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            int m = 0;
            for (a = 0; a < 3; a++) {
                m += l[i * 3 + a] * k[a * 3 + j];
            }
            *ar++ = m;
        }
    }
}

Note also that you are passing the 2D arrays to a function expecting simple pointers to int. You should pass the address of the first matrix elements:

int main() {
    int ar[3][3] = {
        1, 1, 3,
        2, 1, 8,
        3, 8, 1         
    };
    int ar1[3][3] = {
        1, 1, 3,
        2, 1, 8,
        3, 8, 1          
    };
    int ar2[3][3];
    int i, j;

    pointer(&ar2[0][0], &ar[0][0], &ar1[0][0]);
    printf("asas");
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            printf("%d   ", ar2[i][j]);
        }
        printf("\n");
    }
    return 0;            
}

Computing the cell address by hand in the pointer function is useful for learning purposes or if the matrix dimensions are unknown at compile time and the compiler does not support C99 variable length arrays. For your purpose, using the proper types in the multiplication function is much simpler:

#include <stdio.h>

void multiply(int ar[][3], const int l[][3], const int k[][3]) {
    int i, j, a;
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            int m = 0;
            for (a = 0; a < 3; a++) {
                m += l[i][a] * k[a][j];
            }
            ar[i][j] = m;
        }
    }
}

int main() {
    int ar[3][3] = {
        1, 1, 3,
        2, 1, 8,
        3, 8, 1         
    };
    int ar1[3][3] = {
        1, 1, 3,
        2, 1, 8,
        3, 8, 1          
    };
    int ar2[3][3];
    int i, j;

    multiply(ar2, ar, ar1);
    printf("asas");
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            printf("%d   ", ar2[i][j]);
        }
        printf("\n");
    }
    return 0;            
}
Related