Roy
Roy

Reputation: 533

Pointer arithmetic in 2D array

I am learning C++. So, please excuse me for this long question.

I have written the below program for arrays. I understand the base address of the array is returned and the name of the array points to that. So, in the case of a 1D array, I can understand that

arr + 1

returns the address of next item of the array i.e.

arr + 4bytes

However, in the case of a 2D array, it is a little different. What I understand from the below cout statements that in memory arr2D[0], arr2D[1]..arr2D[4] all will be allocated 20bytes one after another as there are 5 cols i.e. 5 * 4 bytes

arr2D & arr2D[0] points to the same base address as expected; lines 43 & 45

So, if I do

arr2D[0] + 5

I get the address of arr2D[1]; line 47. But, when I do

arr2D + 5

I get a memory address 100 bytes from the base address; line 50. I don't understand why. Could anyone explain to me this?

#include <iostream>

using namespace std;

int main() {

int arr[5] = {0,1,2,3,4};

cout << "Printing arr" << endl;
for (int i = 0; i < 5; i++) {
    cout << *(arr + i) << " ";
}
cout << endl;

cout << "Base address of 'arr': " << (unsigned long) arr
     << " EQUALS " << "&arr: " << (unsigned long) &arr
     << endl;

cout << "Address of 2nd item i.e. i = 1 is: " << (unsigned long) (arr+1)
     << endl;

cout << "arr[1] = " << arr[1] << ", "
     << "1[arr] = " << 1[arr] << ", "
     << "*(arr + 1) = " << *(arr + 1)
     << endl << endl;


int arr2D[5][5] = {{1,2,3,4,5},
                   {3,4,5,6,7},
                   {5,6,7,8,9},
                   {7,8,9,10,11},
                   {9,10,11,12,13}};

cout << "Printing arr2D" << endl;
for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 5; j++) {
        cout << *(arr2D[i] + j) << " ";
    }
    cout << endl;
}
cout << endl;


cout << "Base address of arr2D = " << (unsigned long) arr2D << endl; // this is fine

cout << "Address of arr2D[0] = " << (unsigned long) &arr2D[0] << endl; // this is fine

cout << "Address of arr2D[1] = " << (unsigned long) arr2D[1] << " EQUALS "
     << (unsigned long)(arr2D[0] + 5) << endl; // this is fine

cout << "Address of arr2D[1] = " << (unsigned long) arr2D[1] << " NOT EQUALS "
     << (unsigned long)(arr2D + 5) << endl; // I do not understand this, as arr2D and arr2D[0] is same

cout << "Address of arr2D[1][0] = " << (unsigned long)&arr2D[1][0] << endl;

cout << "arr2D[1][0] = " << *((arr2D[0] + 5) + 0) << endl;
}

Upvotes: 1

Views: 133

Answers (2)

eesiraed
eesiraed

Reputation: 4654

arr2D[0] and arr2D point to the same address, but they point to different types.

arr2D[0] is the first row of the 2D array, therefore it decays to a pointer to the first element of that row (a single int). Meanwhile, arr2D is a 2D array (an array of arrays), so it decays to a pointer to the first row (a 5 element array).

As you know, pointer arithmetic is scaled to the size of the objects being pointed to by a pointer. Since arr2D points to 5 element int arrays, each object being pointed to has a size of 4*5=20 bytes (assuming 32-bit ints) so increasing the pointer by 5 results in a difference of 20*5=100 bytes.

Upvotes: 2

Gabriel
Gabriel

Reputation: 869

From cppreference:

When array-to-pointer decay is applied, a multidimensional array is converted to a pointer to its first element (e.g., a pointer to its first row or to its first plane): array-to-pointer decay is applied only once

So arr2D decayed into a pointer to an int array of size five, and the size of that is 20.

Upvotes: 2

Related Questions