1

I know two dimensional array is stored in memory as 1 dimensional array. So following the same logic I am trying to pass the array by reference using a single pointer as is done for 1 dimensional array. Below is my code:

#include<stdio.h>
void display(int *s)
{
    int i,j;
    for(i=0;i<3;i++)
    {
        for(j=0;j<4;j++)
        {
            printf("%d ",s[i][j]);
        }
        printf("\n");
    }
}
int main()
{
    int s[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
    printf("address of the array is %p\n",s);
    printf("value is %p\n",*s);
    int i;
    printf("address of the repective array is\n");
    for(i=0;i<3;i++)
    {
        printf("address of the array is %p\n",s[i]);
    }
    display(s);
    return 0;
}

When i try to compile this get following message:

 twodarray.c: In function ‘main’:
twodarray.c:25:2: warning: passing argument 1 of ‘display’ from    incompatible pointer type [enabled by default]
  display(s);
  ^
twodarray.c:2:6: note: expected ‘int **’ but argument is of type ‘int (*)[4]’
 void display(int *s[3])
      ^

When i run the above code i get segmentation fault error.

user2738777
  • 418
  • 1
  • 5
  • 21

4 Answers4

6

The function parameter is declared as having type int *

void display(int *s)

while the original array passed to the function as the argument has type

int [3][4]

that is implicitly converted to pointer to its first element that has type

int ( * )[4]

As you can see int * and int ( * )[4] are two different types and there is no implicit conversion from one type to another.

Moreover as the function parameter has type int * you may not write within the function expression s[i][j]. because if to apply the subscript operator to this pointer as for example s[i] then this expression is a scalar object of type int. It is not a pointer. So you may not apply the subscript operator the second time.

You have to cast explicitly the argument to the type of the parameter in the function call. For example

display( ( int * )s );

What you want is the following

#include <stdio.h>

void display( int *a, size_t m, size_t n )
{
    for ( size_t i = 0; i < m; i++ )
    {
        for ( size_t j = 0; j < n; j++ )
        {
            printf( "%2d ", a[i * n + j] );
        }
        printf( "\n" );
    }
}

int main( void )
{
    int a[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };

    printf( "The address of the array is %p\n", ( void * )a );

    printf( "The address of the first row is %p\n", ( void * )*a );

    printf("The address of the respective array rows are\n");
    for ( size_t i = 0; i < 3; i++ )
    {
        printf( "address of row %zu is %p\n", i, ( void * )a[i] );
    }

    display( ( int * )a, 3, 4 );

    return 0;
}

The program output might look the following way

The address of the array is 0xbf85d2dc
The address of the first row is 0xbf85d2dc
The address of the respective array rows are
address of row 0 is 0xbf85d2dc
address of row 1 is 0xbf85d2ec
address of row 2 is 0xbf85d2fc
 1  2  3  4 
 5  6  7  8 
 9 10 11 12 

Though it would be better to declare the function the following way that to avoid an unnecessary casting and complicated function implementation

void display( int ( *a )[4], size_t m );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

An array of type int[3][4] is not convertible to a pointer of type int** or int *[] or int*.

The problem is, that

int s[3][4];

will actually be stored in physically continuos memory. To access an arbitrary part of your 3x4 array, the function display needs to know the dimensions of the array.

So you should change your function to:

void display(int (*s)[4])

or use a more flexible technique (Passing multidimensional arrays as function arguments in C).

Community
  • 1
  • 1
manlio
  • 18,345
  • 14
  • 76
  • 126
  • Right, a pointer to the first row. For further details you can take a look at http://stackoverflow.com/q/13554244/3235496. `int (*ptr)[4] = s` first row (address of `s[0][0]`). `++ptr` second row (address of `s[1][0]`). – manlio Jun 13 '15 at 09:33
2

A static two-dimensional array like the one you define here is laid out in memory in a sequential one-dimensional array. But it cannot be used like you tried. Usually compilers wouldn't even produce a binary of this code.

You could technically call the display() function by nastily casting the pointer to int*. That wouldn't help much, since inside the function it is indexed in two dimensions and the compiler has no idea what the dimensions are.

Think of it this way: if you allocate a linear memory block of 100 ints, does it mean it is an array of size 10x10, 2x50 or 4x25? There is no way to know, so you cannot index it as a two-dimensional array. Furthermore, it might not even be known how large the memory block is.

You could, however, index it as a one-dimensional array and multiplying the index manually as s[i*4+j]. This works because, as said, the static array is stored linearly in memory and you are manually telling how to read it.

Just wondering how you managed to actually get that code to compile.

Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74
-1

2 dimensional Arrays are stored in the memory row wise. So, first the array element s[0][0] will be stored then s[0][1],s[0][2],s[0][3],s[1][0]... likewise.

You have taken the pointer to the single dimensional array in your called function as an argument. All you can do is to change printf("%d ",s[i][j]); statement to printf("%d ",*(s + i + j));, this will work.

Last printf statement should be edited to printf("%d ",*(s + 4*i + j)); as suggested by the below comment.