1

I need a little advice. Are all those 3 ways of passing static, multidimensional array (here I have 3-dimensional, I guess for 4 dimensions it would be analogical) to a function are correct?

Here's the code:

#include <stdio.h>    
void fun1(int ***tab, int n, int m, int p)
{
   int i,j,k;
   for(i=0; i<n; i++)
   {
      for(j=0; j<m; j++)
      {
        for(k=0; k<p; k++)
        {
           printf("tab[%d][%d][%d] = %d\n", i, j, k, tab[i][j][k]);
        }
        printf("\n");
      }
      printf("\n");
   }
}

void fun2(int tab[2][3][2])
{
    int i,j,k;
    for(i=0; i<2; i++)
    {
       for(j=0; j<3; j++)
       {
          for(k=0; k<2; k++)
          {
             printf("tab[%d][%d][%d] = %d\n", i, j, k, tab[i][j][k]);
          }
          printf("\n");
       }
       printf("\n");
   }
}

void fun3(int tab[][3][2])
{
    int i,j,k;
    for(i=0; i<2; i++)
    {
       for(j=0; j<3; j++)
       {
          for(k=0; k<2; k++)
          {
            printf("tab[%d][%d][%d] = %d\n", i, j, k, tab[i][j][k]);
          }
          printf("\n");
      }
      printf("\n");
  }
}

int main()
{
    int tab[2][3][2] =
    {
        {{0, 1}, {2, 3}, {3, 4}},
        {{5, 6}, {7, 8}, {9, 10}}
    };

    fun1(tab,2,3,2);
    printf("--------------------------\n");
    fun2(tab);
    printf("--------------------------\n");
    fun3(tab);

    return 0;
}

There seem to be a problem with fun1 but can't really understand what does it mean: expected ‘int ***’ but argument is of type ‘int (*)[3][2]’|. Does it mean that only fun2 and fun3 are valid in this case?

4 Answers 4

2

One is pointer to a pointer to a pointer to an int int ***, and the other is a pointer to an array of dimensions 3 and 2 int (*)[3][2].

Those types are not compatible and their memory layout is not the same. Array is contiguous in memory while pointers to pointers are not.

If you wish to use the first function in a dynamic way where the dimensions are known at runtime then declare it with additional parameters:

void fun1( int n, int m, int p , int a[n][m][p] )...
Sign up to request clarification or add additional context in comments.

2 Comments

@Downvoter Please let me know what you think is wrong.
I am not the down voter, further, I see nothing wrong with your answer. It addresses the question. +1.
2

A 3D array expression does not decay to a triple pointer; it decays to a pointer to a 2D array. Given the code

int arr[X][Y][Z];
fun1( arr );

the expression arr in the call to fun1 will decay to type "pointer to Y-element array of Z-element array of int", so the prototype for fun1 needs to be

void fun1( int (*table)[Y][Z] ) // or int table[][Y][Z]
{
  // do something with table[i][j][k]
}

Note that, in this case, Y and Z must be known at compile time.

If you're using a C99 compiler or a C2011 compiler that still supports variable-length arrays, you can do something like the following:

void fun1( size_t x, size_t y, size_t z, (*table)[y][z] ) // or table[][y][z], or table[x][y][z]
{
  // do something with table[i][j][k]
}

int main( void )
{
  int table[2][3][2] = ...;
  fun1( 2, 3, 2, table );
  ...
}

Note that x, y and z must be declared before they can be used in the array parameter declaration.

Comments

1

It is because an int *** points to a pointer to a pointer. int (*)[a][b] a pointer to an int[a][b].

Arrays are laid out flat in memory, meaning something like int[5][5] uses the same amount of space as an int[25]. Making an int[5][5] compatible with an int** would mean row pointers would need to be allocated somewhere.

Comments

0

One can use the implementation of fun1 or fun4 to pass multidimensional array to a function.

#include <stdio.h>

void fun1(int n, int m, int p, int tab[n][m][p])
{
int i,j,k;

for(i=0; i<n; i++)
{
    for(j=0; j<m; j++)
    {
        for(k=0; k<p; k++)
        {
            printf("tab[%d][%d][%d] = %d\n", i, j, k, tab[i][j][k]);
        }
        printf("\n");
    }
    printf("\n");
}
}

void fun4(int n, int m, int p, int* tab) {
int i,j,k;
for(i=0; i<n; i++)
{
    for(j=0; j<m; j++)
    {
        for(k=0; k<p; k++)
        {
            printf("tab[%d][%d][%d] = %d\n", i, j, k, tab[i*m*p+j*p+k]);
        }
        printf("\n");
    }
    printf("\n");
}
}

void fun2(int tab[2][3][2])
{
int i,j,k;

for(i=0; i<2; i++)
{
    for(j=0; j<3; j++)
    {
        for(k=0; k<2; k++)
        {
            printf("tab[%d][%d][%d] = %d\n", i, j, k, tab[i][j][k]);
        }
        printf("\n");
    }
    printf("\n");
}
}

void fun3(int tab[][3][2])
{
int i,j,k;

for(i=0; i<2; i++)
{
    for(j=0; j<3; j++)
    {
        for(k=0; k<2; k++)
        {
            printf("tab[%d][%d][%d] = %d\n", i, j, k, tab[i][j][k]);
        }
        printf("\n");
    }
    printf("\n");
}
}

int main()
{
int tab[2][3][2] =
{
    {{0, 1}, {2, 3}, {3, 4}},
    {{5, 6}, {7, 8}, {9, 10}}
};

fun1(2,3,2, tab);
printf("--------------------------\n");
fun4(2,3,2, (int*)tab);
printf("--------------------------\n");
fun2(tab);
printf("--------------------------\n");
fun3(tab);


return 0;
}

1 Comment

note, In the second case, the function needs to be called with (int *)tab, or (int *)&tab which works because the array elements are contiguous in memory.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.