Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing multidimensional array to a function C

I'm having problems passing a multidimensional array to a function in C. Both in the typedef and what the argument should be.

Currently, my function def looks like this:

int foo(char *a, char b[][7], int first_dimension_of_array);

I declare an array like this:

char multi_D_array[20][7];

When I try to call the function like this:

foo(d, multi_D_array, 20);

I get the warning that the second argument to the function is from incompatible pointer type. I've tried many of the variations that I've seen online but still can't get it correct. Also, when using GDB, I find that only the first array of the 2D array is passed in. Feedback on what I'm doing wrong would be greatly appreciated.

like image 460
grassclip Avatar asked Dec 01 '25 15:12

grassclip


1 Answers

Big warning: I wouldn't normally handle multi dimensional arrays this way.

I tried this just to check, but this:

#include <stdio.h>

int foo(char b[][7])
{
    printf("%d\n", b[3][4]);
    return 0;
}

int main(int argc, char** argv)
{
    char multi_d_arr[20][7];
    multi_d_arr[3][4] = 42;
    foo(multi_d_arr);
    return 0;
}

Compiles and runs without any issue whatsoever, using gcc -Wall. I'm not sure, honestly, how the second argument can be considered an incompatible pointer type. Works fine.

However, since you ask, how would I handle 2-D arrays? A better way is to use pointers like so:

char** array2d = malloc((MAX_i+1)*sizeof(char*));
for ( i = 0; i < (MAX_i+1); i++ )
{
    array2d[i] = malloc((MAX_j+1)*sizeof(char));
}

Now, just to be clear, the greatest element you can access is array2d[MAX_i][MAX_j].

Don't forget to invert the process when done:

for ( i = 0; i < (MAX_i+1); i++ )
{
    free(array2d[i]);
}
free(array2d);

Now, using this method, subscript notation remains valid, so array2d[x][y] still accesses the right value. Literally speaking, array2d is an array of pointers, and so is each array2d[i].

Why is this a better method? Well, you can have variable size sub-arrays if you so like. All you have to do is change the for-loop. This techique is often used for arrays of strings, particularly in the int main(int argc, char** argv) signature of an app. argv is an array of an array of variable-length strings. Use strlen() to determine their length.

Can you pass this around? Of course. You just received it in main, for starters, but you could also write your function signature like so:

int foo(char** ar2d, const unsigned int size);

and call it:

char** somearray;
/* initialisation of the above */

foo(ar2d, thesizeofar2d);

/* when done, free somearray appropriately */

Just to be clear, your method of including size parameters (like const unsigned int size) is very good practise and you should stick to it.


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!