Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to Pass 2D array without size into function in C

The Question given to me specifically says that a functions takes an integer 2d array and size as parameters. That means, 1) im not allowed to define the size of the array at the declaration. 2) I have to pass the number of rows and cols into the function.

I did it for 1D array previously and it worked, however in the 2D array case it gives a syntax error. I made test codes to check the logic of the syntax. This is the 1D array logic that works. Also this module requires me only to use stido.h library in C. The reason for passing the size of array size is to fill the array in a different function where the loop conditions will take the array size to go through indexes

#include<stdio.h>
void print(int table[],int r);
int main()
{   int r=7,table[r];
    print(table,r);
}

 void print(int table[],int r)
{  printf("table rows is%d\n",r);
} 

However this same logic doesnt work for when I try with a 2D array.(gives a syntax error)

#include<stdio.h>
void print(int table[][],int c,int r);
int main()
{int c=7,r=7,table[c][r];
    print(table,c,r);
}

void print(int table[][],int c,int r)
{printf("table rows is\ntable cols is\n",r,c)
}

Can someone kindly explain why this is happening, and suggest a solution for this problem. ? Thanks in advance

like image 667
Rasanja Dampriya Avatar asked Jun 11 '26 05:06

Rasanja Dampriya


2 Answers

You can't have a 2D array with unspecified dimensions. However, it seems that you have a C99+ compiler and therefore can use a variable-length array. However, you need to reorder the arguments too.

Notice that I use size_t here instead of int for the indices/dimensions - as one might have a table (though unlikely) that has more elements than is possible to represent with an int.

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

void print(size_t, size_t, int [*][*]);

int main(void) {
    size_t c = 7, r = 9;
    int table[c][r];
    print(c, r, table);
}

void print(size_t c, size_t r, int table[c][r]) {
    printf("table rows is %zu\ntable cols is %zu\n", r, c);
}

It compiles in C99, (and those C11 compilers that support the optional VLA extension); and when run, it prints

table rows is 9
table cols is 7

First, you want to know why this isn't possible. It's not allowed by the language standard and the technical reason for this is the compiler cannot calculate offsets into the array when a second dimension isn't known.

A 2D array is just like a 1D array a set of values in memory one after the other. It is not, like in some other languages, an array of arrays. With a 2D array like int a[5][3], you have 5 times 3 ints in a row, all in all 15 ints. For accessing an element, the compiler will compute the offset for you, so if you write e.g. a[2][2], this is the 2*3 + 2th element (there are two rows of 3 columns to skip for the beginning of the third row).

If the compiler doesn't know the second dimension, this calculation of offets is impossible.

Antti Haapala's answer already shows how you can get around this using the C99 feature variable length arrays. That's a good approach, but unfortunately, with C11, this feature is optional, so there may be compilers not supporting it. If you're sure to only use compilers supporting VLAs (which is the great majority of all modern C compilers), go with the code from this answer.


When passing an array to a function, instead of the array, a pointer to its first element is passed (the array decays as a pointer). So the following declarations are the same:

void print(size_t n, int arr[]);
void print(size_t n, int *arr);

With that knowledge, you could be tempted to write it differently and do the offset calculations yourself:

void print(size_t r, size_t c, void *data)
{
    int *arr = data;
    // access arr[2][2]:
    int v = arr[2*c + 2];
}

And indeed, this is very likely to work, but be aware this is undefined: int[] and int[][] are not compatible types. For details on this idea, see this question with two quite interesting answers. Bottom line: This kind of code will work with a very high probability. Still, to be sure, don't do it....


So, if you don't have variable length arrays, and if you don't want to rely on something not perfectly well-defined, the only other way would be to actually build an array of arrays by having an array of pointers:

int row1[3] = {0, 1, 2};
int row2[3] = {3, 4, 5};
int *rows[2] = { row1, row2 };

Then you can pass it like this:

void print(size_t r, size_t c, int **arr)
{
    int a = arr[0][2]; // 2
}

Of course, this isn't a 2D array any more, it's a replacement construct that can be used in some similar fashion.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!