Passing 2D array to a function using single pointer .

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • radha gogia
    New Member
    • Feb 2015
    • 56

    Passing 2D array to a function using single pointer .

    Code:
    #include <stdio.h>
    void print(int *arr, int m, int n)
    {
    int i, j;
    for (i = 0; i < m; i++)
    for (j = 0; j < n; j++)
    printf("%d ", *((arr+i*n) + j));
    }
    int main()
    {
    int arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
    int m = 3, n = 3;
    
    print((int *)arr, m, n);
    return 0;
    }
    Why can't I use *(*(arr+i)+j) notation inside printf in print function .Although it's a pointer to an integer still I am operating on the address of first element of array , so what's wrong in this ?
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    What's not working?

    I ran your code and got 1 2 3 4 5 6 7 8 9 displayed, which is correct.

    Comment

    • radha gogia
      New Member
      • Feb 2015
      • 56

      #3
      If I am using *(*(arr+i)+j) instead of *((arr+i*n) + j) , then I am unable to get the correct OP , it shows error :
      invalid type argument of 'unary *'

      I am unable to get this .

      Comment

      • radha gogia
        New Member
        • Feb 2015
        • 56

        #4
        If I am using *(*(arr+i)+j) instead of *((arr+i*n) + j) , then I am unable to get the correct OP , it shows error :
        invalid type argument of 'unary *'

        I am unable to get this .

        Comment

        • radha gogia
          New Member
          • Feb 2015
          • 56

          #5
          If I am using *(*(arr+i)+j) instead of *((arr+i*n) + j) , then I am unable to get the correct OP , it shows error :
          invalid type argument of 'unary *'

          I am unable to get this .

          Comment

          • weaknessforcats
            Recognized Expert Expert
            • Mar 2007
            • 9214

            #6
            You can't use this:

            *(*(arr+i)+j)

            because arr is an address so arr + i is also an address. But
            *(arr + i) is an int. This makes *(arr+i) + j an int. Now you use another dereferencing * on an int so you get an error.

            Comment

            • radha gogia
              New Member
              • Feb 2015
              • 56

              #7
              Thanks , I got the point

              Comment

              • hackr
                New Member
                • Apr 2017
                • 3

                #8
                1) When both dimensions are available globally (either as a macro or as a global constant).

                Code:
                #include <stdio.h>
                const int M = 3;
                const int N = 3;
                 
                void print(int arr[M][N])
                {
                    int i, j;
                    for (i = 0; i < M; i++)
                      for (j = 0; j < N; j++)
                        printf("%d ", arr[i][j]);
                }
                 
                int main()
                {
                    int arr[][N] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
                    print(arr);
                    return 0;
                }
                Run on IDE
                Output:
                Code:
                1 2 3 4 5 6 7 8 9
                2) When only second dimension is available globally (either as a macro or as a global constant).

                Code:
                #include <stdio.h>
                const int N = 3;
                 
                void print(int arr[][N], int m)
                {
                    int i, j;
                    for (i = 0; i < m; i++)
                      for (j = 0; j < N; j++)
                        printf("%d ", arr[i][j]);
                }
                 
                int main()
                {
                    int arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
                    print(arr, 3);
                    return 0;
                }
                Run on IDE
                Output:

                Code:
                1 2 3 4 5 6 7 8 9
                The above method is fine if second dimension is fixed and is not user specified. The following methods handle cases when second dimension can also change.

                3) If compiler is C99 compatible
                From C99, C language supports variable sized arrays to be passed simply by specifying the variable dimensions (See this for an example run)

                Code:
                // The following program works only if your compiler is C99 compatible.
                #include <stdio.h>
                 
                // n must be passed before the 2D array
                void print(int m, int n, int arr[][n])
                {
                    int i, j;
                    for (i = 0; i < m; i++)
                      for (j = 0; j < n; j++)
                        printf("%d ", arr[i][j]);
                }
                 
                int main()
                {
                    int arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
                    int m = 3, n = 3;
                    print(m, n, arr);
                    return 0;
                }
                Run on IDE
                Output on a C99 compatible compiler:

                Code:
                1 2 3 4 5 6 7 8 9
                If compiler is not C99 compatible, then we can use one of the following methods to pass a variable sized 2D array.

                4) Using a single pointer
                In this method, we must typecast the 2D array when passing to function.

                Code:
                #include <stdio.h>
                void print(int *arr, int m, int n)
                {
                    int i, j;
                    for (i = 0; i < m; i++)
                      for (j = 0; j < n; j++)
                        printf("%d ", *((arr+i*n) + j));
                }
                 
                int main()
                {
                    int arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
                    int m = 3, n = 3;
                 
                    // We can also use "print(&arr[0][0], m, n);"
                    print((int *)arr, m, n);
                    return 0;
                }
                Run on IDE
                Output:

                Code:
                1 2 3 4 5 6 7 8 9
                Last edited by Niheel; Apr 19 '17, 03:34 PM. Reason: marketing link signature edited out. Please read guidelines.

                Comment

                • weaknessforcats
                  Recognized Expert Expert
                  • Mar 2007
                  • 9214

                  #9
                  When you pass an argument to a function in C the argument is a copy of the variable used by the calling function. In the case of arrays, what is passed is the address of the array so the function in using that address operates on the original array that belongs to the calling function.

                  For this reason you cannot pass an array to a function.

                  What does happen is the function has a copy of the address of the array but has lost the dimensions so it has no idea how large the array is. This is called decay-of-array. True you can provide access to the dimensions by using variables from somewhere but there is no guarantee the values are accurate. If these values change in the called function, then the calling function has bad info and crashes. Any dimensional values must be passed (in C) by address.

                  If the array is on the stack and you pass the address to a function, that function can pass it anywhere else, save it to disc, etc. Then when the original function completes, the stack frame is deleted and all those saved copies of the array pointers now are invalid and when accessed will crash the program.

                  So addresses of arrays must be heap addresses which brings up memory allocations, leaks, reference counting whereby the array cannot be deleted until the last copy of the pointer is deleted.

                  etc.
                  etc.

                  This dire weakness of arrays in C is the main reason for the <vector> template in C++.

                  Comment

                  • radha gogia
                    New Member
                    • Feb 2015
                    • 56

                    #10
                    Thanks a lot , I understood the concept now .

                    Comment

                    Working...