Search code examples
cdouble-pointer

Why this code is giving compilation error?


I am trying to learn about double pointers.I am trying to print a 2d array by passing the address of the array to a function.But compilation error is coming.I am unable to understand why ??

Below is the code.

#include<stdio.h>
#include<stdlib.h>
void print(int **,int,int);
int main()
{

    int i,j;
    int a[][3]={
                {1,0,1},{1,1,1},   {1,1,1}
            };
            print(a,3,3);
            return 0;
}
void print(int **A, int n11, int n12)
{
    int i,j;
   for(i=0;i<3;i++)
            {
                for(j=0;j<3;j++)
                {
                    printf("%d  ",*((A+i*n12)+j);
                }
                printf("\n");
            }
}

Error log---

set_matrix.c: In function 'main':
set_matrix.c:29:19: warning: passing argument 1 of 'print' from incompatible poi
nter type [-Wincompatible-pointer-types]
             print(a,3,3);
                   ^
set_matrix.c:9:6: note: expected 'int **' but argument is of type 'int (*)[3]'
 void print(int **,int,int);
  ^

Solution

  • I am trying to learn about double pointers

    I am not sure the terminology is correct, but I wouldn't refer a pointer to pointer as a double pointer because you can easily get confused with a double* & **.

    Consider int x=1.0. You can have :

    int *ptr=&x; // You make ptr point to x(ie x's memory address).
    

    But remember that pointer is also a type - to be precise an object. An object occupies memory. To store the address of ptr (ie &ptr), you need a pointer to a pointer so :

    int **ptr_to_ptr=&ptr; // says ptr_to_ptr is a pointer to an (int*)
    

    The bigger problem here is how can we declare a pointer to int a[][].

    For an array say, int a[3], the pointer that should represents it should be of following format - int (*p)[3]. We say p is a pointer to an array of 3 integers.

    Here the difference is that you're having an array of arrays ie int a[][3]. The pointer to this array should of the this format - int (*p)[][3]. We say p is pointer to array, each element of this array itself is an array of 3 integers.

    Now comparing int a[3] and int a[3][3]

            int a[3]                    |           int a[3][3]
    ________________________________________________________________________
          &a[0] ~ a (1)                 |   &a[0][0] ~ &a[0] ~ a
                                        |               |------> follows (1)
                                        |              
         a[0] is an int                 |        a[0] is an int[3]
                                        |
                                        |
     you pass '&a' to int(*)[]          |     you pass '&a' to int(*)[][]
     (You omit the &, you get-but the   |   (You omit the &, you get-but the 
     argument is of type int * error)   |argument is of type int (*)[3] error)
                                        |
    ________________________________________________________________________
    

    So the right way to implement your programme is :

    #include<stdio.h>
    #include<stdlib.h>
    void print(int (*)[][3],int); //You need to pass only the  rows
    int main()
    {
      int i,j;
      int a[][3]={
        {1,0,1},{1,1,1},{1,1,1}
      };
      print(&a,3); // You can programmtically determine the number of rows
      return 0;
    }
    void print(int (*A)[][3], int x) // You cannot have int (*A)[][]
    {
      int i,j;
      for(i=0;i<3;i++)
      {
        for(j=0;j<3;j++)
        {
          printf("%d\t",(*A)[i][j]);
        }
        printf("\n");
      }
    }