Based on the description, the most likely interpretation is that you are passing a pointer to an int **
object, and foo
allocates memory for that object, so you'd have
void foo( int ***out )
{
*out = ...; // omitting actual allocation here since it's homework,
// but I can guarantee it won't be a single statement
}
int main( void )
{
int **pairs;
...
foo( &pairs );
...
}
Note than an object of T **
is not a 2-dimensional array; it can be used to implement something that can be indexed like a 2D array, but the "rows" don't have to be contiguous or even the same length. It basically looks something like this:
pairs pairs[i] pairs[i][0], pairs[i][1]
int ** int * int
+---+ +---+ +---+---+
| +-+-----> | +-+---------> | | |
+---+ +---+ +---+---+
| +-+------+
+---+ | +---+---+
| +-+---+ +--> | | |
+---+ | +---+---+
... |
| +---+---+
+-----> | | |
+---+---+
IOW, you have an object pairs
that points to a sequence of int *
, each of which (pairs[i]
) points to a sequence of int
. Because of how the []
subscript operator works, you can index into this structure using 2D array notation (pairs[i][j]
), but otherwise it doesn't look or act like a 2D array.
So I'm assuming the job of foo
is to allocate the memory for a structure like that, where each pairs[i]
points to a sequence of 2 int
. Since it needs to write a new value to pairs
, we need to pass a pointer to pairs
. Since pairs
has type int **
, that means the expression &pairs
has type int ***
.
I can tell you this will be a multi-step process - you will need to make multiple calls to malloc
or calloc
. The diagram above should give you some hints on how to do that.