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.

21
  • Looks like you have initialized a 2D array but trying to pass it to the functions as a 1D array. I could be wrong though Commented Jun 13, 2015 at 9:04
  • Yes, it is a 2D array,but isn't a 2D array same as 1D array in memory? Commented Jun 13, 2015 at 9:05
  • 1
    void display(int *s) change to void display(int s[3][4]) if you want printf("%d ",s[i][j]); Commented Jun 13, 2015 at 9:06
  • or void display(int s[][4]) or void display(int (*s)[4]) Commented Jun 13, 2015 at 9:07
  • 1
    @ user2738777 , The name of a 2D array gets converted into a pointer to the first array and not to a pointer to an int or a pointer to a pointer to an int. Google "pass 2D array to function" or try the changes suggested by me or @BLUEPIXY Commented Jun 13, 2015 at 9:13

4 Answers 4

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 );
Sign up to request clarification or add additional context in comments.

Comments

3

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.

Comments

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).

1 Comment

Right, a pointer to the first row. For further details you can take a look at stackoverflow.com/q/13554244/3235496. int (*ptr)[4] = s first row (address of s[0][0]). ++ptr second row (address of s[1][0]).
-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.

3 Comments

It will not, s + i + j is missing a multiplier for one of the indexers.
Pls see the for loops that are being implemented in the code, you will come to know how it will work.
Yes, the loops go as 0..2 and 0..3, so if you just add them up, you'll get 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5... (and not my downvote on the answer, just want to say)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.