简体   繁体   中英

passing a pointer to 2D array of pointers in C

I have seen some of the other answers on this topic but dont really understand them enough to fit them to my problem. I have a 2D array of pointers to char that I want to pass to a function.

If the array is declared: char *params[50][50]; (50 is just picked arbitrarily)

and the function prototype is: void test (char ***results);

How would I call the function? everything I try ends up with an incompatible pointer warning

Also what is the most correct way to then refer to the members of the array while inside the function? is it simply: results[x][y]; ?

Thanks

you can't, pointers to pointers and pointers to arrays are different things.

void test (char *results[50][50]);
void test (char *results[][50]);
void test (char *(*results)[50]);

are all equivalent prototypes for the function that you are looking for.

Suplement: If you want to use the same function for arrays with varying lenght for the dimension you'd have to use VLA (variable length array) as function arguments:

void test (size_t n, char *results[n][n]);
void test (size_t n, char *results[][n]);
void test (size_t n, char *(*results)[n]);

This only works if you have a compiler that is conforming to C99.

Observe that the parameter for the size comes before the array, such that it is known there.

Also you don't have to declare the arrays themselves with variable length to use this feature for the function parameters. But if you do be careful that you don't allocate large matrices on the stack, otherwise you may easily have a stackoverflow.

If you declare an array as

char *array[N][M];

and pass it to a function as

test(array)

then the prototype to the function will need to be either

void test(char *(*arr)[M])

or

void test(char *arr[][M])

In either case, arr has type "pointer to M-element array of pointer to char ". This is not the same type as char *** , and there's no really good or clean way to convert between the two.

Had you allocated dynamcally allocated array in the following manner, then the prototype would be correct:

char ***array = malloc(sizeof *array * N); 
if (array)
{
  size_t i;
  for (i = 0; i < N; i++)
  {
    array[i] = malloc(sizeof *array[i] * M);
    if (array[i])
    {
      size_t j;
      for (j = 0; j < M; j++)
      {
        array[i][j] = some_initial_pointer_value();
      }
    }
  }
}

Note that in this case, the type of array is char *** .

If you're working with arrays declared as T a[M][N] , and you want to write a function that will accept arrays of different sizes, then you can either use the VLA syntax as suggested by Jens, or you could do something like this:

void test(char **a, size_t rows, size_t cols)
{
  size_t i, j;
  ...
  some_pointer_value = a[i * rows + j]; 
  ...
  a[i * rows + j] = some_pointer_value;
}

...
test(&array[0][0], 50, 50);

In this case, we explicitly pass the address of the first element of the array and the array dimensions as separate parameters. Within the body of test we treat the array as having 1 dimension ( char *a[rows * cols] ) and compute the offset manually. Note that this only works for arrays that are contiguously allocated; this won't work with the version that does piecemeal allocation for each row in the array above.

My C is a little rusty but:

char *params[][];

is a 2D array of char * pointer, not char. If you wanted a 2D char array it is defined as:

char params[valuex][valuey];

Iit will be static memory allocation, only available in definition scope, i mean you leave the scope you loose the array if it is not the behaviour you are looking for try dynamic allocation).

You can then pass this array to a function by defining the function prototype as:

void foo(char param[valuex][valuey] );

Regards

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM