3

Let's say I declare and initialize the following multi-dimensional array in C++:

unsigned a[3][4] = {
    {12, 6, 3, 2},
    {9, 13, 7, 0},
    {7, 4, 8, 5}
};

After which I execute this code:

cout << a << endl; // output: 0x7fff5afc5bc0
cout << a + 1 << endl; // output: 0x7fff5f0afbd0
cout << *a << endl; // output: 0x7fff5afc5bc0
cout << *a + 1 << endl; // output: 0x7fff5f0afbc4

I just don't understand what is happening here.

  1. a is the address of the first element, right? In single-dimensional arrays, *a should be the value of the first element, but instead it's the same as a?! What does *a even mean in this context?

  2. Why is a + 1 different from *a + 1?

3
  • 4
    There's plenty of such post on SO, please do a little search Commented Oct 4, 2015 at 19:46
  • Try dereferencing *(*a + 1) and **(a+1) and you'll see where each point. Commented Oct 4, 2015 at 19:55
  • Remember that the first element of a 2-D array is a 1-D array Commented Oct 5, 2015 at 9:18

2 Answers 2

3

You should try and find some good documentation about pointers, arrays, and array-to-pointer decay. In your case, unsigned a[3][4] is a bi-dimensional array of type unsigned [3][4]. Whenever you refer to it as a, it decays to a pointer to unsigned[4], so the decayed type of a is unsigned (*)[4]. Therefore dereferencing it gives you an array, so *a is the array [12, 6, 3, 2] (technically it's the pointer to the first element into the array).

Now, a+1 means "increment the pointer to unsigned[4] by 1", in your case it "jumps" 4 unsigneds in the memory, so now a+1 points to the "row" indexed by 1 in your example. Dereferencing it *(a+1) yields the array itself ([9,13,7,0]) (i.e. the pointer to the first element of it), and dereferencing again gives you the first element, i.e. **(a+1) equals 9.

On the other hand, *a+1 first dereferences a, so you get the first row, i.e. [12,6,3,2] (again, technically the pointer to the first element of this row). You then increment it by one, so you end up pointing at the element 6. Dereferencing it again, *(*a+1), yields 6.

It may be helpful to define a equivalently as

typedef unsigned T[4]; // or (C++11) using T = unsigned[4];
T a[3]; // Now it's a bit more clear how dereferencing works
Sign up to request clarification or add additional context in comments.

Comments

2

Two dimensional array is array of array. You can visualize a as

a = { a[0], a[1], a[2]} 

and a[0], a[1], a[2] as

a[0] = { a[0][0], a[0][1], a[0][2], a[0][3]};
a[1] = { a[1][0], a[1][1], a[1][2], a[1][3]};
a[1] = { a[2][0], a[2][1], a[2][2], a[2][3]};

Analysis of your first question

a is the address of the first element, right?

Yes a is the address of the first element, and first element of a is a[0] which is the address of the first element of a[0][0].

*a should be the value of the first element, but instead it's the same as a?

Yes *a should be the value of the first element that refer a[0]. And we see a[0] is the address of a[0][0] so as a . Thus *a have same value as a which is the address of a[0][0].

What does *a even mean in this context?

Previously answered, *a is the address of first arrays first element a[0][0], and *(a+1) is the address of second arrays first element a[1][0].

And analysis of your second question

Why is a + 1 different from *a + 1?

At this time perhaps you can answer your owns question.

a is the address of a[0] then
a+1 is the address of a[1] which hold address of a[1][0]. You can print the value by

cout<<**(a+1)<<endl; // 9

Other way *a is the value of a[0] which is the address of a[0][0]. So *a+1 is the address of a[0][1]. You can print the value as

cout<<*(*a+1)<<endl; // 6

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.