-1

In my code I need to pass a pointer to an array of pointers as a function argument. Code snippets:

struct foo * foos[] = {NULL, NULL, NULL};
some_function(&foos);

and:

static void some_function(struct foo ** foos) {
    foos[0] = get_a_foo();
    /* some more code here */
}

This works as expected (after some_function() returns, foos[] contains the pointers I set there), but I get a compiler warning for the call to some_function():

note: expected ‘struct foo **’ but argument is of type ‘struct foo * (*)[3]’

What’s the correct way to accomplish what I want (i.e. pass a pointer to the array of pointers to the function, so that the function can change pointers in the array)?

user149408
  • 5,385
  • 4
  • 33
  • 69

4 Answers4

1

Pass it as some_function(foos)

Raman
  • 2,735
  • 1
  • 26
  • 46
  • This is the correct answer. In C, an array is converted to a pointer to it's first element automatically in _many_ (not all) situations. More about it [here.](https://stackoverflow.com/questions/18518255/why-is-array-name-a-pointer-to-the-first-element-of-the-array#18518282) The reason why there's a warning is because there's an additional level of indirection ( `&foos` ), which is a bug. – mogu Jan 27 '18 at 17:55
0

struct foo ** is a pointer to a (single) pointer to a struct foo, not a pointer to an array of pointers, hence the compiler warning.

An easy way to silence the compiler warning is to call the function as follows:

some_function(&foos[0]);

This will pass a pointer to the first member, i.e. a struct foo **, rather than to the whole array; the address is the same in both cases.

user149408
  • 5,385
  • 4
  • 33
  • 69
0

If I understand what you are trying to do (fill your array of pointers with a call to a function), then your understanding of how to accomplish that is a bit unclear. You declare foos, which itself is an array. (an array of what? pointers).

You can treat it just like you would treat an array of char (from the standpoint that you can simply pass the array itself as a parameter to a function and operate on the array within a function) You can do that and have the changes visible in the caller because despite the array address itself being a copy in the function, the values it holds (the individual pointer address) remains the same.

For example:

#include <stdio.h>

char *labels[] = { "my", "dog", "has", "fleas" };

void fillfoos (char **f, int n)
{
    int i;

    for (i = 0; i < n; i++)
        f[i] = labels[i];
}


int main (void) {

    char *foos[] = { NULL, NULL, NULL };
    int i, n = sizeof foos / sizeof *foos;

    fillfoos (foos, n);

    for (i = 0; i < n; i++)
        printf ("foos[%d] : %s\n", i, foos[i]);

    return 0;
}

Above foos is simply treated as an array passed to the function fillfoos which then loops over each pointer within foos filling it with the address to the corresponding string-literal contained in labels. The contents of foos is then available back in main, e.g.

Example Use/Output

$ ./bin/fillptp
foos[0] : my
foos[1] : dog
foos[2] : has

If I misunderstood your question, please let me know and I'm happy to help further.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
0

You need a pointer to an array as clearly mentioned in the warning. Below is a minimal code sample that explains the same.

#include<stdio.h>

typedef struct foo{

}FOO;

static void some_function(FOO* (*foos)[]) {
// foos above is a pointer to an array of pointers.
// Refer the link to start with a simple example.
// Access it like foos[0][0] which is the same as (*foos)[0]
    /* some more code here */
}

int main(int argc, char **argv) {
    FOO* foos[]={0,0,0}; // Here you have an array of pointers
    some_function(&foos);
}
sjsam
  • 21,411
  • 5
  • 55
  • 102