Abhiram M V
Abhiram M V

Reputation: 3

How to pass multidimensional arrays as argument?

#include <stdio.h>

void input(int* r1, int* r2, int* c1, int* c2,
  int arr1[*r1][*c1], int arr2[*r2][*c2]);
void matrix_multiply(int* r1, int* r2, int* c1, int* c2, 
  int arr1[*r1][*c1], int arr2[*r2][*c2], int result[50][50]);
int ouput_matrix(int*r1 , int* c2, int result[50][50]);

int main(void)
{
    int arr1_out[50][50];
    int arr2_out[50][50];
    int result_out[50][50];

    int a = 0;
    int* r1 = &a;

    int b = 0;
    int* r2 = &b;

    int c = 0;
    int* c1 = &c;

    int d = 0;
    int* c2 = &d;

    input(r1,r2,c1,c2,arr1_out,arr2_out);
    matrix_multiply(r1, r2,c1, c2,arr1_out, arr2_out,result_out);

    output_matrix(r1,c2,result_out);

}

void input(int* r1,int* r2,int* c1,int* c2,int arr1[*r1][*c1],int arr2[*r2][*c2])
{
    printf("Enter the no. of rows and columns of first matrix ");
    scanf("%d %d\n",r1,c1);

    printf("Enter the no. of rows and columns of second matrix");
    scanf("%d %d\n",r2,c2);

    while(*c1 != *r2)
    {
        printf("Matrix cannot be multiplied...no. of columns of 1st matrix not equal to no. of rows of 2nd matrix");

        printf("Enter the no. of rows and columns of first matrix ");
        scanf("%d %d\n",r1,c1);

        printf("Enter the no. of rows and columns of second matrix");
        scanf("%d %d\n",r2,c2);
    }

    printf("Enter the elements of matrix 1");
    for(int i = 0;i < *r1;i ++)
        for(int j = 0;j < *c1;j ++)
        {
            printf("Enter element a%d%d",i + 1,j + 1);
            scanf("%d",&arr1[i][j]);
        }


    printf("Enter the elements of matrix 2");
    for(int i = 0;i < *r2;i ++)
        for(int j = 0;j < *c2;j ++)
        {
            printf("Enter element b%d%d",i + 1,j + 1);
            scanf("%d",&arr2[i][j]);
        }
}

void matrix_multiply(int* r1,int* r2,int* c1,int* c2,int arr1[*r1][*c1],int 
arr2[*r2][*c2],int result[50][50])
{
    for(int i = 0; i < *r1; ++i)
        for(int j = 0; j < *c2; ++j)
        {
            result[i][j] = 0;
        }

    for(int i = 0; i < *r1; ++i)
        for(int j=0; j < *c2; ++j)
            for(int k=0; k < *c1; ++k)
            {
                result[i][j]+=arr1[i][k]*arr2[k][j];
            }
}

int ouput_matrix(int*r1 , int* c2, int result[50][50])
{
    printf("\nOutput Matrix:\n");
    for(int i = 0; i < *r1; ++i)
        for(int j = 0; j < *c2; ++j)
        {
            printf("%d  ", result[i][j]);
            if(j == *c2-1)
                printf("\n\n");
        }
    return 0;
}

Errors:

matrix_multi.c:32:53: runtime error: variable length array bound evaluates to non-positive value 0
matrix_multi.c:32:58: runtime error: variable length array bound evaluates to non-positive value 0
matrix_multi.c:32:72: runtime error: variable length array bound evaluates to non-positive value 0
matrix_multi.c:32:77: runtime error: variable length array bound evaluates to non-positive value 0

Upvotes: 1

Views: 146

Answers (2)

Bob__
Bob__

Reputation: 12759

Consider the posted input function

void input(int* r1,int* r2,int* c1,int* c2,int arr1[*r1][*c1],int arr2[*r2][*c2]) {/* */}

The number of rows and columns of both arrays are passed as pointers, the intent beeing to modify their value inside the function, but they are also initialized to zero outside the function and used to decare the VLA parameters, effectively two zero-sized arrays. This can't be done.

A viable approach would be to ask the user the dimensions first, check if those are valid and only then declare the arrays and pass those to the various functions. Something like the following.

#include <stdio.h>
#include <stdlib.h>

typedef int value_t;

int input_matrix( const char *format, size_t rows, size_t cols, value_t mat[rows][cols] );
void print_matrix( const char *format, size_t rows, size_t cols, value_t mat[rows][cols] );

int ask_matrix_dimensions( const char *msg, int *rows, int *cols );

void multiply_matrices( size_t rows, size_t inner, size_t cols,
                        value_t mat_a[rows][inner], value_t mat_b[inner][cols],
                        value_t mult[rows][cols] );

int main(void)
{
    int ra, ca;
    if ( ask_matrix_dimensions("the first matrix", &ra, &ca) != 2 )
        return EXIT_FAILURE;

    int rb, cb;
    if ( ask_matrix_dimensions("the second matrix", &rb, &cb) != 2 )
        return EXIT_FAILURE;

    if ( ca != rb )
    {
        fputs("Error: Wrong dimensions, the two matrices cannot be multiplied.", stderr);   
        return EXIT_FAILURE;
    }
    value_t mat_a[ra][ca];
    if ( input_matrix("%d", ra, ca, mat_a) == EOF )
        return EXIT_FAILURE;

    value_t mat_b[rb][cb];
    if ( input_matrix("%d", rb, cb, mat_b) == EOF )
        return EXIT_FAILURE;

    puts("\nMatrix a:");
    print_matrix("%3d", ra, ca, mat_a);
    puts("Matrix b:");
    print_matrix("%3d", rb, cb, mat_b);

    value_t mat_c[ra][cb];
    multiply_matrices(ra, ca, cb, mat_a, mat_b, mat_c);
    puts("Matrix b:");
    print_matrix("%4d", ra, cb, mat_c);

    return EXIT_SUCCESS;
}

int input_matrix( const char *format, size_t rows, size_t cols, value_t mat[rows][cols] )
{ 
    int ret;
    for(size_t r = 0; r < rows; ++r)
    {
        for(size_t c = 0; c < cols; ++c)
        {
            printf("Enter element (%zu, %zu): ", r + 1, c + 1);
            while ( (ret = scanf(format, &mat[r][c])) != 1 )
            {
                if (ret == EOF)
                {
                    fputs("Error: Unexpected end of input.", stderr);
                    return ret;
                }
                puts("Please enter a valid number.");
                for (int ch = getchar(); ch != EOF  &&  ch != '\n'; ch = getchar());
            }
        }
    }
    return 0;
}

void print_matrix( const char *format, size_t rows, size_t cols, value_t mat[rows][cols] )
{
    for (size_t r = 0; r < rows; ++r)
    {
        for (size_t c = 0; c < cols; ++c)
        {
            printf(format, mat[r][c]);
        }
        putchar('\n');
    }
}

int ask_matrix_dimensions( const char *msg, int *rows, int *cols )
{
    printf("Please enter the number of rows and columns of %s: ", msg);
    int ret;
    while ( (ret = scanf("%d%d", rows, cols)) != 2  ||  *rows < 1  ||  *cols < 1)
    {
        if (ret == EOF)
        {
            fputs("Error: Unexpected end of input.", stderr);
            break;
        }
        puts("Please enter two positive numbers.");
        for (int ch = getchar(); ch != EOF  &&  ch != '\n'; ch = getchar());
    }
    return ret;
}

void multiply_matrices( size_t rows, size_t inner, size_t cols,
                        value_t mat_a[rows][inner], value_t mat_b[inner][cols],
                        value_t mult[rows][cols] )
{
    for (size_t i = 0; i < rows; ++i)
    {
        for (size_t j = 0; j < cols; ++j)
        {
            mult[i][j] = mat_a[i][0] * mat_b[0][j];
        }
        for (size_t k = 1; k < inner; ++k)
        {
            for (size_t j = 0; j < cols; ++j)
            {
                mult[i][j] += mat_a[i][k] * mat_b[k][j];
            }   
        }        
    }
}

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 310990

You defined functions that have variable length arrays as their parameters.

void input(int* r1,int* r2,int* c1,int* c2,int arr1[*r1][*c1],int arr2[*r2][*c2]);
void matrix_multiply(int* r1,int* r2,int* c1,int* c2,int arr1[*r1][*c1],int 
arr2[*r2][*c2],int result[50][50]);

But you are passing zero values as the sizes of the arrays.

int a = 0;
int* r1 = &a;

int b = 0;
int* r2 = &b;

int c = 0;
int* c1 = &c;

int d = 0;
int* c2 = &d;

Variable length arrays may not have a zero size.

You should at least write

int a = 50;
int* r1 = &a;

int b = 50;
int* r2 = &b;

int c = 50;
int* c1 = &c;

int d = 50;
int* c2 = &d;

But as the user specifiers in the functions the number of rows and columns and the arrays actually have fixed sizes then you should declare the functions like

void input(int* r1, int* r2, int* c1, int* c2,
  int arr1[][50], int arr2[][50]);
void matrix_multiply(int* r1, int* r2, int* c1, int* c2, 
  int arr1[][50], int arr2[][50], int result[][50]);

Upvotes: 1

Related Questions