3

I am trying to print a two dimensional array by assigning to a pointer. With this I can print one dimensional fine, but 2 dimensional causes a segmentation fault.

void printOutput(int **array,int row, int col)
{
    int i = 0, j = 0;
    int dualArray[2][2] = {{1,2},{3,4}};
    int singleArray[]={1,2,3};
    int *sa = singleArray;

    printf ("Output values :\n");
    for(i=0;i<3;i++)
        printf("%d ",sa[i]);
    printf("\n");

    int **da = dualArray;

    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {   
            printf("%d ",da[i][j]);
        }
        printf("\n");
    }
}

Output values :
1 2 3 
Segmentation fault (core dumped)

If I can access 1D array (sa) by assigning int *sa = singleArray; (I can print sa[i]), then why cannot I access a 2D array (da) int **da = dualArray;? I get a segmentation fault when I access a 2D array.

Someone please let me know the reason. Thanks.

cokeman19
  • 2,405
  • 1
  • 25
  • 40
shiva
  • 85
  • 7
  • 1
    An array of arrays is not the same as a pointer to pointer. See e.g. [this old answer of mine](https://stackoverflow.com/questions/18440205/casting-void-to-2d-array-of-int-c/18440456#18440456) for a "drawing" of the difference. – Some programmer dude Apr 28 '18 at 19:02
  • 1
    Also, remember that arrays *decay* to a pointer to their first element. In the case of `singleArray` that is `&signleArray[0]` which of course if of type `int *`. In the case of `dualArray` that is `&dualArray[0]` which is a pointer to an array of type `int (*)[2]`. – Some programmer dude Apr 28 '18 at 19:03
  • @Ajay I think you meant `int (*da)[2]` – user3386109 Apr 28 '18 at 19:12
  • 1
    From gdb I got this error message: `main.c: In function 'printOutput': main.c:15:16: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] int **da = dualArray;` – Ṃųỻịgǻňạcểơửṩ Apr 28 '18 at 19:14
  • Also, you **cannot overload** C functions. You are trying to create a function that supports both type `int *` and `int **` data. – Ṃųỻịgǻňạcểơửṩ Apr 28 '18 at 19:20
  • Try with int **da = &dualArray; – Abhijit Pritam Dutta Apr 28 '18 at 19:34
  • Possible Duplicate of https://stackoverflow.com/questions/3911400/how-to-pass-2d-array-matrix-in-a-function-in-c: You might want to wonder how to pass in any 2D array and then print it out. – Ṃųỻịgǻňạcểơửṩ Apr 28 '18 at 19:43
  • Thanks all for your time. i can use like this to print int *da = dualArray; printf("%d ",*((da+i)+j)); if this for printing purpose. – shiva Apr 28 '18 at 19:52
  • 1
    I don't really understand your code though it is certainly incorrect since it does not use the array that is passed through or row or col at all. However, I am thinking that you are building a function to **print out a 1D or 2D array**. I provided some sample code for you to use. Did you use double arrays or arrays to pointers? – Ṃųỻịgǻňạcểơửṩ Apr 28 '18 at 20:00
  • i have used arrays to pointer, created array in main function and passed as a pointer to printOutput funcntion. This is my modified code : void printOutput(int *array,int row, int col) { int i = 0, j = 0; printf ("Output values :\n"); for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { printf("%d ",*((array+i)+j)); } printf("\n"); } } – shiva Apr 28 '18 at 20:30

2 Answers2

1
#include<stdio.h>
#include<stdlib.h>

int main()
{
    int row=2,col=3;
    int i = 0, j = 0;
    int dualArray[2][3] = {{1,2,5},{3,4,6}};
    int singleArray[]={1,2,3};
    int *sa = singleArray;

   printf ("Output values :\n");
   for(i=0;i<3;i++)
       printf("%d ",sa[i]);
    printf("\n");

    int **dda;   //Double pointer

    int *da[2];  //It is array of two pointer 
                 //Means it will store two elements, which will be some pointer themselves

    dda=da;      //array name is pointer to first element so here dda is pointing to first element of da
    int (*ss)[3]=dualArray;  //Here ss is pointer to array of 3 element
    da[0]=ss;                //am storing this pointer at da[0], comprising of first row
    ss=ss+1;                 //Now ss is incremented, it will increment by its size.
                             //sizeof(*ss) is 12 bytes, 3elements x sizeof(int)
    da[1]=ss;                //So now ss points to second row, 
                             //Pointer to second row is stored in da[1]


    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {   
            printf("%d ",*(*(dda+i)+j)); //de-referencing twice to get the element as done in @D array
        }                               //But here dda double pointer
        printf("\n");
    }


}

Here I have modified your code to main function so that you can directly run it and see its output.

Consider the following things that will be helpful.

1.Double pointer is mostly use when at declaration time we don't know the actual size of 2D array, & we making it dynamically.

2.When a 2D array is passed to a function, it gets decay to pointer to array; ie pointer to array of number of elements as there are columns in a row. So, pointer to array of first row is passed to a function where we receive it.

3.As I told above 2D array is not passed as pointer to pointer, it is passed as pointer to array( You can also think like function should know how many numbers of columns are there in the row? if you are just passing the double pointer. how would it know??)

4.For making illustration of Double Pointer in function you have taken, I have done some changes which i explained too..

5.I have taken double pointer dda that is pointing to array of pointers da having two elements which will be pointer themselves.

Rest i have explained through comments in program.

May be this will help.

0

Are you trying to build a function which takes in a two-dimensional pointer (have to be two-dimensional) along with its dimensions and printing out its contents?

You need to known that a pointer to a pointer is not the same as a 2D array aka array of arrays. You must know that C does not really have two-dimensional or higher-dimensional arrays: they are just arrays of arrays. Dynamic memory should be used if you want the 2D array to be a pointer to a pointer. See How to pass 2D array (matrix) in a function in C? to get how to pass in a 2D array and then printing out the result.

I also don't fully understand your code. In your code, you claimed that it works for 1D arrays, but it does not work for 2D arrays. However, your code don't use row or col at all, but rather generate a preset 1D and 2D arrays.

Additionally, you cannot overload C functions. Therefore, printOutput either supports 1D or 2D arrays. Here is my sample code which works for 2D arrays along with a sample input-output:

void printOutput(int row, int col, int array[row][col])
{
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {   
            printf("%d ", array[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

int main() {
    int m1[2][2] = {{1,2},{-2,0}};
    int m2[3][3] = {{1,5,6},{3,2,7},{8,4,9}};
    int m3[2][5] = {{0,1,2,3,4},{5,6,7,8,9}};
    int m4[1][7] = {{-3,-2,-1,0,1,2,3}};

    printOutput(2, 2, m1);
    printOutput(3, 3, m2);
    printOutput(2, 5, m3);
    printOutput(1, 7, m4);
    return 0;
}

The output would be:

1 2                                                                                                                              
-2 0                                                                                                                             

1 5 6                                                                                                                            
3 2 7                                                                                                                            
8 4 9                                                                                                                            

0 1 2 3 4                                                                                                                        
5 6 7 8 9                                                                                                                        

-3 -2 -1 0 1 2 3