Pankaj Mahato
Pankaj Mahato

Reputation: 1113

When passing 2d array to function what is the difference between single pointer and double pointer?

We can pass a 2d array as a single pointer and as well as a double pointer. But in the 2nd case the output is not as expected. So what is wrong in the 2nd code?

Method 1:

#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;
}

Output:

1 2 3 4 5 6 7 8 9

Method 2:

#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;
    int n = 3;
    print((int **)arr, m, n);
    return 0;
}

Output:

1 3 5 7 9 3 0 -1990071075 0

Upvotes: 3

Views: 297

Answers (2)

David Ranieri
David Ranieri

Reputation: 41017

The first one is undefined behavior: Accesing a 2D array using a single pointer.

The second one is simply wrong, you can't pass a 2D array (arr[][3]) to an array of int pointers (*arr[]), take a look to Correct way of passing 2 dimensional array into a function:

void print(int *arr[], int m, int n)

Must be

void print(int arr[][3], int n) /* You don't need the last dimesion */

or

void print(int (*arr)[3], int n) /* A pointer to an array of integers */

But this way the column in arr[][3] must be globally defined. Isn't any other workaround?

Under C99 you can use VLA's (Variable-length array):

void print(int rows, int cols, int arr[rows][cols])

Upvotes: 5

Marek Vavrusa
Marek Vavrusa

Reputation: 256

Alter Mann is right, but the main problem in Method 2 is this code:

*((arr+i*n) + j)

Since arr is now type of int *arr[], the element size is sizeof(int *) and not sizeof(int) as in the first case. So when f.e. arr = 0, then arr + 1 equals to 0 + sizeof(int*) instead of 0 + sizeof(int) as in the first case. It would work okay if the arr was casted to (int*) like:

*(((int *)arr+i*n) + j)

TL;DR you're jumping through the array by the pointer size, not an integer size.

My personal suggestion is to use pointers, but access it like an array:

int *arr[];
return arr[i][j];

This works every time unlike the pointer arithmetic that might bite you with the step size, like it did with your case.

Upvotes: 1

Related Questions