Acessing a 2D array inside a function - c

I have a function which accepts int* pInput[] as an argument.
void Process(int* pInput[], unsigned int num);
I have to call this function via 2 methods as
main()
{
int *pIn[2];
int input[2][100] = {0};
pIn[0] = ( int* )malloc( 100 * sizeof( int) );
pIn[1] = ( int* )malloc( 100 * sizeof( int) );
Process( pIn, 2 );
Process( ( int** )input, 2 );
}
Then how can i access each value of pInput inside function 'Process'?I cannot access it directly as pIn[0][0].

how can i access each value of pInput inside function 'Process'?I cannot access it directly as pIn[0][0].
No! You can access it exactly that way: pInput[0][0] if the input you pass is pIn. This is because pIn is an array of int*s I.e. it's of type int *[n] each of its element pointing to an array of ints. It would decay into int**.
However, if you want to pass input, a 2D array of ints, you've to do more since a 2D array doesn't decay into a double pointer, T** but into a pointer to an array, T (*) [n]. This is because array decay is not recursive, it happens only to the first level. Alternatively, you can do this (Live example)
pIn[0] = input[0];
pIn[1] = input[1];
and now pass pIn to Process. Here pIn is a surrogate for input and it needs to have as many elements as input, which is not a very elegant solution. A better way to pass input, when you know the dimensions during compile-time is
void Process(int (*pInput)[100], size_t rows) { }
void Process(int input [2][100], size_t rows) { }
/* These two are the same; the compiler never sees the `2`. input's type is int(*)[100] */
Read on array decay to understand the situation better.
Aside
Do I cast the result of malloc? No, you do not need to cast the return value of malloc in C.
What should main() return in C and C++? The return type of main should be int.
Related
C-FAQ: My compiler complained when I passed a two-dimensional array to a function expecting a pointer to a pointer.
What is array decaying?
Why can we omit the first dimension of a multidimensional array when we are passing it to a function

In your process() function you just need to access it normally like any 2d array as below. Calling both ways are same.
void Process( int * pInput[], unsigned int num)
{
printf(" %d", pInput[0][0]); //printing value of pInput[0]
printf(" %d", pInput[1][0]); //printing value of pInput[1]
pInput[0][0] = 8054; // changing its value.
pInput[1][0] = 8055; // changing its value.
}
int main()
{
int *pIn[2];
int input[2][100] = {0};
pIn[0] = ( int* )malloc( 100 * sizeof( int) );
pIn[1] = ( int* )malloc( 100 * sizeof( int) );
// assigning value to array.
pIn[0][0] = 23;
pIn[0][1] = 2;
pIn[1][0] = 5689;
pIn[1][1] = 5643;
Process( pIn, 2 ); //calling process funtion
printf(" %d", pIn[1][0]); //printing the changed value by process funtion.
}

You are getting confused because you are using different types when there's no need for such. Arrays follow the same rules of indirection as any other type. If you would allocate a plain int dynamically, you would write int* x = malloc(sizeof(*x));. Simply do the very same thing when it comes to arrays. Don't confuse things by mixing in the "arrays decay to pointers" rule.
So we have int input[2][100], very straight-forward, it is a plain 2D array. Now if you want to allocate that dynamically, you will need a pointer to such an array:
int (*pIn)[2][100]; // pointer to an array of int [2][100].
pIn = malloc(sizeof(*pIn));
And the whole program would then be:
#include <stdlib.h>
void Process (size_t num, int pInput[num][100])
{
}
int main (void)
{
int (*pIn)[2][100];
int input[2][100] = {0};
pIn = malloc(sizeof(*pIn));
if(pIn == NULL)
{
// error handling
return 0;
}
Process(2, *pIn);
Process(2, input);
free(pIn);
return 0;
}
Comments:
size_t is the most correct type to use for array sizes, as it is the type returned by the sizeof operator. So it is just an unsigned integer with a fancy name.
int pInput[num][100] in the function will actually decay into an array pointer to an array of 100 int. You don't need to know that to use it though, simply use pInput[x][y] and pretend it is a 2D array. The important thing here is to understand that the array is not passed by value.
The correct form of main is int main (void).
Casting the result of malloc is pointless.
Always check the result of malloc and remember to clean up allocated data.

Related

Program does not find highest number in array as intended

This program is supposed to return the highest number in the array "array". But it only returns the highest number between the first and second numbers. Why?
#include <stdio.h>
#include <stdlib.h>
int HighestNumber(int* array)
{
int highest = INT_MIN;
for(size_t x = 0; x < sizeof(array) / sizeof(array[0]); x++)
if(array[x] > highest)
highest = array[x];
return highest;
}
int main()
{
int *array = (int*)malloc(4*sizeof(int));
array[0] = 66;
array[1] = 552;
array[2] = -17;
array[3] = 1000;
printf("%d", HighestNumber(array));
return 0;
}
The function parameter array has the pointer type int *.
int HighestNumber(int* array);
So the expression sizeof(array) / sizeof(array[0]) is equivalent to expression sizeof( int * ) / sizeof( int ) and yields usually either value 2 or 1 dependent of the sizes of pointers and integers.
You need explicitly to pass the number of elements in the array As for example
int HighestNumber(int* array, size_t n );
Pay attention to that the user can pass 0 for the parameter n. In this case using your approach to the function definition the function can return an invalid value.
The function should be declared and defined the following way. As the function does not change the processed array then the first parameter should have the qualifier const.
size_t HighestNumber( const int *array, size_t n )
{
size_t highest = 0;
for ( size_t i = 1; i < n; i++ )
{
if ( array[highest] < array[i] )
{
highest = i;
}
}
return highest;
}
And the function is called like
printf("%d\n", array[HighestNumber(array, 4 )] );
or
size_t highest = HighestNumber(array, 4 );
printf( "The largest number is %d at the position %zu\n",
array[highest], highest);
As you can see the advantage of such function definition is that you can also determine the position where the highest element is stored in the array.
Pay attention to that you need to free the dynamically allocated memory.
free( array );
The sizeof trick doesn't work on pointers!
If applied to pointers you get the (truncated) ratio between the size of a pointer, which is always the same, no matter how large your array is, and the size of a single element in that array, so in your case with int* most likely either 2 (64-bit system, typically 8-byte pointers, 4-byte int) or 1 (32-bit system, typically 4-byte pointers, 4-byte int), though other systems can yield yet other values, but still not the required one (apart from accidentally matching array size...).
To use sizes on array you need to pass it explicitly by another parameter:
int highestNumber(size_t length, int* array)
{
int highest = INT_MIN;
while(length--)
{
if(*array > highest)
{
highest = *array;
}
++array;
}
return highest;
}
while you can then apply the sizeof trick on the array being passed to:
int array[4];
// assign values to
// array has not yet decayed to pointer, thus you can do:
int highest = highestNumber(sizeof(array)/sizeof(*array), array);
However in your example you use a dynamically allocated array – these only can be stored in pointers, thus there's no way around tracking the size explicitly:
size_t length = 4;
int* array = malloc(length * sizeof(*array));
// assign values
int highest = highestNumber(length, array);
Final note: You might as well use the length/size as second parameter, of course; having it as first would allow for:
int highestNumber(size_t length, int array[length]);
which is fully equivalent, as for the outermost dimension an explicitly specified array size is ignored and the parameter still remains a pointer (note that this does not apply for further dimensions), but this declaration expresses more explicitly what the function actually expects as arguments.
Edit (stealing from Vlad from Moscow's answer):
As you do not (intend to) modify the array within the function it is a good choice to accept a pointer to const – this allows to use both non-const and const arrays while the original function signature excludes the latter without need:
int highestNumber(size_t length, int const* array)
int highestNumber(size_t length, int const array[length]);
The moment you pass array to the function HighestNumber(), you lose the size information of the array. This is called an array-to-pointer decay.
To the function HighestNumber() it only sees a pointer, without knowing anything about the array.
Consider pass the array size as the second parameter to the function, such as
int HighestNumber(int* array, size_t num) {
// ..
}
An array decays to a pointer in function parameters. sizeof on a pointer then returns the size of the pointer, and not the pointed to data.
Possible solution:
Pass the size of the array as the second argument.
int HighestNumber(int* array, size_t size) {
//...
}

Pass pointer of an array of multi-dimensional arrays to a function, specifying bounds

Let's say I have multiple (a variable number) of 2D arrays (which may even be variable-length):
int a[2][2] = {{1,2},{3,4}};
int b[2][2] = {{5,6},{7,8}};
...
which I now want to pass to a function. I do not want to copy the 2D arrays into 3D array. However, I want to specify the bounds so that the function knows the dimensions of the 2D arrays so that I can index them conveniently with [i][j]
How can I format the functions' signature so that it accepts a pointer to an array (of unknown length) which contains 2D arrays of which it does now the dimensions?
E.g. something like
void myfunc(int[][3] *test, int len)
though of course this is syntactically invalid. Is specifying the bounds of arrays inside an array (passed by pointer) impossible in C? Will I be forced to move a and b into pointers, or forced to copy them into a 3D array?
If your compiler supports a variable length arrays you can write
void myfunc( int rows, int cols, int a[rows][cols] );
Take into account that the third parameter is implicitly converted to the type int ( * )[cols], that is within a function you are dealing with a pointer to one dimensional array. Nevertheless you can use expressions like
for ( int i = 0; i < rows; i++ )
{
for ( int j = 0; j < cols; j++ ) a[i][j] = value;
}
Otherwise if the compiler does not support variable length arrays and the second dimension of all arrays is the same then the function can be declared like
void myfunc( int ( *a )[2], int rows );
Take into account that this declaration
int[][3] *test
in any case is incorrect.
If you want to pass several two-dimensional arrays then you can within main declare a one dimensional array like
int a[2][2] = {{1,2},{3,4}};
int b[2][2] = {{5,6},{7,8}};
//...
int ( *p[] )[2] = { a, b, /*...*/ };
and then pass it to a function.
In this case the function will look like
void myfunc( int ( **p )[2], size_t n );
Here is a demonstrative program
#include <stdio.h>
void myfunc( int ( **p )[2], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < 2; j++ )
{
for ( size_t k = 0; k < 2; k++ ) printf( "%d ", p[i][j][k] );
putchar( '\n' );
}
putchar( '\n' );
}
}
int main(void)
{
int a[2][2] = {{1,2},{3,4}};
int b[2][2] = {{5,6},{7,8}};
int ( *p[] )[2] = { a, b };
myfunc( p, sizeof( p ) / sizeof( *p ) );
return 0;
}
Its output is
1 2
3 4
5 6
7 8
If the first dimension of the arrays is not fixed and varies then you could pass also to the function an array of first dimensions of the arrays
If you have two things you need to pass to a function, you either
pass two separate arguments; or
create some kind of data structure that contains (pointers to) said things, and pass (a pointer to) that.
It doesn't matter if your things are arrays or anything else.
The same thing holds when you have a variable number of things. You can pass a variable number of arguments to a function, but that's a separate topic, so let's concentrate in option 2. In this case your data structure should be an array of pointers to things.
OK so how do you create one when your thing has a complex type, like an array (of arrays of pointers to functions that return a pointer to an array, or whatever)? The answer is simple: use a typedef.
typedef int MyThing[2][2]; // could be anything
MyThing one = {{1,2},{3,4}};
MyThing two = ...; // etc
MyThing* manyPointersToThings[] = {&one, &two};
void myFunc(int nThings, MyThing things[nThings]) {
// in here, each things[i] is a *pointer* to MyThing
(*things[0])[1][2] = 42;
// whatever
}
This works for any kind of thing. If your thing is in fact an array, there is another option: your data structure could store pointers to first elements of your arrays, rather than pointers to arrays themselves.
typedef int MyThing[2]; // this type names an *element* of your array
MyThing one[2] = {{1,2},{3,4}};
MyThing two[2] = ...; // etc
MyThing* manyPointersToThings[] = {one, two}; // note no & here
void myFunc(int nThings, MyThing things[nThings]) {
// in here, each things[i] is a pointer to the first element of an array
things[0][1][2] = 42;
// whatever
}
With this option, you gain some flexibility, as your arrays need not all be of the same size. You also lose that ugly dereference in parentheses.
For completeness, here are prototypes of the same functions sans typedef:
void myFunc(int nThings, int (*things[nThings])[2][2]) // version 1
void myFunc(int nThings, int (*things[nThings])[2]) // version 2
These are a bit more flexible than typedef versions, because now you can use a variable (another parameter) instead of the hardcoded number 2.
If you have trouble writing down things like the above, try this.

What is the type of my array? [duplicate]

This question already has answers here:
Return a 2d array from a function
(10 answers)
How to return matrix (2D array) from function? (C)
(3 answers)
Closed 8 years ago.
I have the following function :
int** myfunc() {
int array[2][2];
// operation on the array
return array;
}
And the following error from the compiler :
cannot convert 'int (*)[2]' to 'int**' in return
So my question is : how can I return my array ?
So my question is : how can I return my array ?
You cannot. The array named array has function scope and goes out of scope when the function myfunc returns. This means the array no longer exists and trying to access it will invoke undefined behaviour. Also, the return type of myfunc is int **. In the return statement
return array;
the array named array is implicitly converted to a pointer to its element. int array[2][2]; defines array to be an array of 2 elements of type int[2], i.e., an array of 2 integers. Therefore, array in the return statement is implicitly converted to type int (*)[2], i.e., a pointer to an array of 2 integers. This explains the error message.
If you want to return an array from a function, you should allocate it dynamically using malloc which should later be freed in the caller after its use.
// you should change function signature to take the array size.
// and change return type to (int *) to return a pointer to the
// first element of the dynamically allocated array
int *myfunc(int len) {
int *array = malloc(len * sizeof *array);
if(array == NULL) {
printf("error in memory allocation\n");
return NULL;
// handle it
}
// operation on the array
return array;
}
Please note that an array type object is a contiguously allocated nonempty set of objects with a particular member object type, called the element type. Therefore, a 2-D array is not a new type. It's just an array type where the elements of the array are themselves arrays. This mean we have the following equivalence -
// an automatic array of 200 elements allocated on the stack
int auto_array[10][20];
// a dynamic array of 200 elements allocated on the heap
int *dynamic_array = malloc((10 * 20) * sizeof *array);
printf("%d\n", auto_array[4][8];) // prints element in the 5th row, 9th column
printf("%d\n", dynamic_array[4*10 + 8]); // prints element in the 5th row, 9th column
This only fixes the compiler error
The compiler is already giving you the correct type to return, you just need to give the type a name to return it easily:
typedef int (*myArrayPtr)[2];
myArrayPtr myFunc() {
int foo[2][2];
return foo; //Compiles, BUT DON'T USE IT (see below)
}
Alternatively, you can write the function declaration like this (but please don't, this should only be done in code that tries to win the International Obfuscated C Code Contest):
int (*myFunc())[2] {
int foo[2][2];
return foo; //Compiles, BUT DON'T USE IT (see below)
}
This approach actually works
The code above returns a pointer to a local variable, which is automatically deallocated when myFunc() returns. If the calling function uses the returned pointer in any way, anything might happen. To return a 2D array correctly, you need to malloc() it:
typedef int myArray[2];
myArray* myFunc() {
myArray* foo = malloc(2*sizeof(*foo));
foo[1][1] = 7;
return foo;
}
Note, that one of the two dimensions is encoded in the array type, while the other one is implicit in the pointer. That is why the sizeof of *foo must be multiplied by the size of the first dimension. Of course, you can also encode both dimensions in the array type, but that requires you to write an additional dereference when you access its elements:
typedef int myArray[2][2];
myArray* myFunc() {
myArray* foo = malloc(sizeof(*foo));
(*foo)[1][1] = 7;
return foo;
}
Arrays and pointers, while deceptively similar, are not the same thing in C.
You're trying to return a local variable, memory for which is allocated on the stack. The local variable will be popped off the stack as soon as your function exits, which is why most compilers give you a warning when you try to return the address of a local variable. The returned address points to a value that is gone.
What you need to do, is declare an int** & return it. You can allocate memory dynamically using malloc() present in the malloc.h header. Something like the following should work.
#include <stdio.h>
#include <malloc.h>
int** myfunc()
{
// Allocate memory so array can hold two int *
int** array = malloc(sizeof(int *) * 2);
// Allocate memory for each of the pointers that the array holds
// We want to reserve space for two integers in each slot.
array[0] = malloc(sizeof(int) * 2);
array[1] = malloc(sizeof(int) * 2);
array[0][0] = 0;
array[0][1] = 1;
array[1][0] = 2;
array[1][1] = 3;
return array;
}
int main(void)
{
int i, j;
int **x;
x = myfunc();
for (i = 0; i < 2; ++i) {
for (j = 0; j < 2; ++j) {
printf("%d", x[i][j]);
}
}
return 0;
}
Don't forget to free() the contents of the array when you're done with it.
Arrays are not first-class data types in C, you cannot return an array by copy, and returning a reference to a local variable will have undefined behaviour (and is never good).
There are three ways (at least) to do what you are attempting. The most usual (not to mention safe and efficient) is to have the caller own the array, then pass the array into the function by reference and have the function operate on the provided array:
void myFunc( int array[2][2] )
{
// operate directly on caller's array
}
The second method is to wrap the array in a struct, which is a first-class data type and can be exchanged by copy or reference. Note for large structures, exchange by copy can become expensive computationally.
typedef struct
{
int array[2][2] ;
} array_container ;
array_container myFunc()
{
array_container contained_array ;
return contained_array ;
}
Dynamically allocating the array within the function is a possibility, but leaves the question of who is responsible for freeing the memory and how and when it is safe to do so. However although I would not recommend it:
#define ARRAY_DIM1 2
#define ARRAY_DIM2 2
int** myfunc()
{
int** array = malloc( sizeof(int*) * ARRAY_DIM1 ) ;
int* array_memory = malloc( sizeof(int) * ARRAY_DIM1 * ARRAY_DIM2 ) ;
int i = 0 ;
for( i = 0; i < ARRAY_DIM1; i++ )
{
array[i] = array_memory[i * ARRAY_DIM2]
}
return array;
}

Is it possible to still address the individual elements of an array via a pointer?

I am trying to write a program that will mutliply two numbers, but output the result in binary, showing the calculation (i.e. shifting the rows). I'm storing the binary numbers as an array of 32 characters, and each element is either 1 or 0.
I have a function that will convert decimal to binary character array, but then my array only exists within the function, but I need to use the array within another function and also within main. I was thinking it might be possible to use pointers to change the value of the array in main from within my converter function, so then the array will exist in main and can be used in other functions. Is this possible?
I've declared two pointers to character arrays:
char (*binOne)[32];
char (*binTwo)[32];
if I pass the pointer as a parameter to the function, can I still access each element? Sorry if I'm not making much sense here.
In C, most of the time array behaves like pointer to its first element, so what you probably want to do is:
void foo(char* arr){
//some stuff, for example change 21-th element of array to be x
arr[20] = 'x';
}
int main(){
char binOne[32];
char binTwo[32];
// change array binOne
binOne[20] = 'a';
foo(binOne);
// now binOne[20] = 'x'
foo(binTwo);
// now binTwo[20] = 'x'
}
A continuation of what I added as a comment:
In C, if you want to modify/return an array, you'll do that by passing a pointer to it as an argument. For example:
int toBinary(char *buff, int num) { /* convert the int, return 1 on success */ }
...
char buff[32];
toBinary(buff, 9001);
In C, an array's name is it's address, it's the address of the first element:
buff == &buff == &buff[0]
Yes, this is possible. But you only need a pointer to the array not an array of pointers.
You need to prototype like
e.g.
void int_to_arr(int n, char *arr);
void arr_to_int(int *n, char *arr);
in main(){
char *binarr = calloc(32, sizeof(char));
int n = 42;
int_to_arr(n, binarr);
}
void int_to_arr(int n, char *arr)
{
//do you conversion
//access array with
// arr[i]
}
void arr_to_int(int *n, char *arr)
{
//do you conversion
//access array with
// *n = result;
}

Passing arrays and matrices to functions as pointers and pointers to pointers in C

Given the following code:
void
foo( int* array )
{
// ...
}
void
bar( int** matrix )
{
// ...
}
int
main( void ) {
int array[ 10 ];
int matrix[ 10 ][ 10 ];
foo( array );
bar( matrix );
return 0;
}
I don't understand why I get this warning:
warning: passing argument 1 of β€˜bar’ from incompatible pointer type
Although 'foo' call seems to be ok.
Thanks :)
Well, it's certainly not well understood by the C community as can be seen by glancing over SO. The magic is, all of the following are totally, 100%, equivalent:
void foo(int (*array)[10]);
void foo(int array[][10]);
void foo(int array[10][10]);
void foo(int array[42][10]);
It is very important to draw the distinction of a pointer and an array. An array is not a pointer. An array can be converted to a pointer to its first element. If you have a pointer you have this:
--------
| ptr | -------> data
--------
However, if you have an array, you have this:
---------------------------
| c1 | c2 | c3 | ... | cn |
---------------------------
With the pointer, the data is at a whole other planet, but linked to by the pointer. An array has the data itself. Now, a multi-dimensional array is just an array of arrays. The arrays are nested into a parent array. So, the sizeof of your array is:
(sizeof(int) * 10) * 10
That is because you have 10 arrays, all of which are arrays of 10 integers. Now, if you want to pass that array, it is converted. But to what? A pointer to its first element. The element type is not a pointer, but an array. As a consequence, you pass a pointer to an array of 10 int:
int (*)[10] // a pointer to an int[10]
It is neither a array of int*, nor a int**. You may ask why the array is not passed as an int**. It's because the compiler has to know the row-length. If you do an array[1][0], the compiler will address a place sizeof(int) * 10 bytes apart from the begin of the 2 dimensional array. It decodes that information in the pointer-to-array type.
So, you have to chose among one of the above fully equivalent function prototypes. Naturally, the last one is just confusing. The compiler just silently ignores any number written in the most outer dimension if a parameter is declared to be an array. So i would also not use the second last version. Best is to use the first or second version. What is important to remember is that C has no (real) array parameters! The parameter will be a pointer in the end (pointer to array in this case).
Note how the multi-dimensional case of above is similar to the degenerate, one dimensional case below. All of the following 4 versions are fully equivalent:
void foo(int *array);
void foo(int array[]);
void foo(int array[10]);
void foo(int array[42]);
Passing multi-dimensional arrays in C is a tricky subject. See this FAQ.
The question to ask is how you'll be using bar. If you always know it will be passed a 10x10 array then rewrite it as
bar(int matrix[10][10]);
If you want to cope with arrays of varying dimensions then you might have to pass in the lengths:
bar(int *matrix, int width, int height);
The problem is that the data structure matrix[10][10] is actually not a table of ten pointers to array[10]'s, but it is an sequential array of 100 integers. The proper signature for bar is
bar (int matrix[10][10])
If you actually want to represent the matrix using indirection and have int **matrix as the parameter type for bar, then you need to allocate it differently:
int *matrix[10];
int my_data[100];
int i;
for (i = 0; i < 10; i++) { matrix[i] = &(my_data[i * 10]); }
bar(matrix);
Now 'matrix' matches the type int **. 'matrix' is an array of ten pointers, and you can pass it by pointer, hence getting the second *.
Here is some code to practice on - it contains all possible types of passing 2dimensional array and code to access element values
#include <stdio.h>
#define NUMROWS 2
#define NUMCOLUMNS 5
#define FILL_ARRAY() \
*array[0] = '1'; \
(*array)[7] = '2'; \
*(array[1]) = '3'; \
*(*(array+1)+1) = '4'; \
*(array[0]+3) = '5'; \
*(*array+2) = '7'; \
array[0][1] = '6';
void multi_01( char (*array)[NUMCOLUMNS] ) { FILL_ARRAY(); }
void multi_02( char array[][NUMCOLUMNS] ) { FILL_ARRAY(); }
void multi_03( char array[NUMROWS][NUMCOLUMNS] ) { FILL_ARRAY(); }
void multi_04( char **array ) { FILL_ARRAY(); }
void multi_05( char *array[] ) { FILL_ARRAY(); }
void multi_06( char *array[NUMCOLUMNS] ) { FILL_ARRAY(); }
int main(int argc, char **argv)
{
int i;
char mystr[NUMROWS][NUMCOLUMNS] = { { 'X', 'X', 'X', 'X'}, {'X','X','X'} };
char *pmystr[sizeof(mystr)/sizeof(*mystr)];
int numcolumns = sizeof(*mystr);
int numrows = sizeof(mystr)/sizeof(*mystr);
for( i=0; i<numrows; i++ ) pmystr[i] = *(mystr+i);
multi_01( mystr ); multi_02( mystr ); multi_03( mystr );
multi_04( pmystr ); multi_05( pmystr ); multi_06( pmystr );
printf("array '%s', '%s'\n", mystr[0], mystr[1]);
getc(stdin);
return 0;
}
You should define bar as:
bar( int* matrix )
In C all arrays should be passed as int* (or type_of_element* for other types).
int ** would be ok if your data was really an array of pointers. int[*data[] for example. Thats what you get in main(int argc, char *argv[]).
int **matrix
would indicate that you have a pointer to a pointer to int. That's commonly used to indicate a pointer to an array of pointers (also called a vector). That's definitely NOT the case with
int matrix[10][10]
which is a more of a pointer to a single section of memory sized for 10x10 ints. Try changing to:
void bar(int *matrix[])

Resources