InsaneCoder
InsaneCoder

Reputation: 8288

Passing a 2D array to a function as pointer to array of integers

The following code works, but is it OK?

#include <iostream>

using namespace std;

void display(int (*A)[3], int m, int n)
{
        for(int i=0;i<m;i++)
                for(int j=0;j<n;j++)
                        cout << A[i][j] << endl;
}

int main()
{
        int arr[][3] = {{1,2,3},{4,5,6}};
        display(arr,2,3);
}

Since A is a pointer to integer array of size 3, effectively aren't we just referring to the first row? It works because the 6 elements are in contiguous locations, hence we are traversing 6 times from the address of the first item. Is my understanding correct?

Upvotes: 2

Views: 58

Answers (4)

eerorika
eerorika

Reputation: 238451

Since A is a pointer to integer array of size 3, effectively aren't we just referring to the first row?

Yes, A points to the first (at index zero) element of the 2D array. There are a total of two elements in the 2D array. Each of them is a 1D array i.e. a row of the 2D array. A[i] is the ith (zero based) row. A[i][j] is the jth element of the ith row.

Upvotes: 0

NathanOliver
NathanOliver

Reputation: 181007

The code is fine. Arrays decay to a pointer to their first element. That means a 2d array will decay into a pointer to an array.

That said, you can also pass the array by reference, which allows you to not have to specify the array size since it can be deduced for you. Changing you function to

template <size_t rows, size_t cols>
void display(const int (&A)[rows][cols])
{
    for(int i=0;i<rows;i++)
            for(int j=0;j<cols;j++)
                    cout << A[i][j] << endl;
}

allows you to call it like display(arr); instead of display(arr,2,3);.

Upvotes: 0

Lundin
Lundin

Reputation: 214930

Yes, it is fine. Like with any pointer arithmetic, you are using a pointer to the first object. The first object of an int[2][3] array is of type int[3] and a pointer to that object is of type int(*)[3], an array pointer.

Your code is completely equivalent to void display(int A[2][3], int m, int n). In this case the compiler silently adjusts the parameter to a pointer to the first object "between the lines", so you end up with exactly the same code. Though my version here is preferred since it is more readable.

As for why you can use A[i][j], think of A[i] as pointer arithmetic on objects of sizeof(int[3]).


C would also allow you to do void display(int m, int n, int A[m][n]), but that isn't possible in C++.

Upvotes: 1

dbush
dbush

Reputation: 225237

The way you're passing this array is correct.

Anytime you pass an array to a function, you're actually passing a pointer to the first element. In this case, each element of the array is a int[3].

For the same reason, if you defined arr as int arr[2] then you can pass it to a function expecting a int *.

Upvotes: 0

Related Questions