2

I am mis-understanding something about the code below. From my understanding the tester declaration should return a pointer to the first array of two elements, i.e. [1,2], and so *(tester+1) should return [3,4], which only has 2 elements so how does it make sense to call (*(tester + 1))[2] . This example prints the number 5 by the way. Any clarifications much appreciated.

int main() {
    int tester[][2]{ 1,2,3,4,5,6 };
    cout << (*(tester + 1))[2] << endl;
    return 0;
}

4 Answers 4

4

When you declare a 2-dimensional array, all the elements are contiguous. The entire array is a single object, so you're not going out of bounds when you just exceed one of the row limits, so longer as you're still in the array. So the next element after tester[1,1] is tester[2,0], and that's what (*(tester + 1))[2] accesses.

Sign up to request clarification or add additional context in comments.

4 Comments

note that opinion is divided over whether it's allowed to read out of bounds of one array to access other members of a larger object that the array is a sub-object of.
Some people visualise two-dimensional array as square memory area, while in fact it is, as you said contiguous. Thus it's better to imagine it like one row.
@M.M I have worked on projects that included state of the art bounds checking compilers for C. It is pretty much agreed that it is okay to return an error for stuff like struct { char a[5]; int b;} c; c[7]=0; - i.e. You can't rely on c[7] being in or not in b. Portable code does not guarantee padding, although ABIs do. I know that much code assumed that you can go past row bounds in a 2d array, so our compiler had to allow it by default.
@KrazyGlew There's a difference between structure members and array elements. There can be padding between structure members, but not between the rows of 2-D arrays. Arrays are stored contiguously in row-major order.
1

[2] is higher than the highest element at [1] because the index starts at [0]

There are three arrays.

[1,2] positions 0,0 and 0,1
[3,4] positions 1,0 and 1,2
[5,6] positions 2,0 and 2,1

Since all of the arrays are next to each other in the data segment, going out of bounds on the second array (tester + 1) bleeds over into the third array giving you the first element of the third array. i.e. position 1,2 is the same as 2,0

Comments

1

int tester[][2]{ 1,2,3,4,5,6 } creates a 3 by 2 array.

tester[0][0] = 1
tester[0][1] = 2
tester[1][0] = 3
tester[1][1] = 4
tester[2][0] = 5
tester[2][1] = 6

The compiler creates an array using the least amount of memory possible based on your specifications. [][2] explicit says to organize the data in such a fashion that there a x rows and 2 columns. Because you put 6 elements into the tester array, the compiler decides the number of rows to assign by dividing the number of total elements by the number of columns.

Furthermore, (*(tester + 1))[2], is equivalent to tester[2], which would access the element in the first column of the third row. Thus returning 5.

2 Comments

Please avoid using backticks for emphasizing words. You can use bold or italic for that.
No problem I'll work on it! @Paul I've been meaning to experiment more with the different ways to emphasize.
0

It is another way to write this code which means you define vector but it acts like 2-dimensional array.

  int main() {
     int tester[3][2]{ {1,2},{3,4},{5,6} };
     std::cout<< tester[1][2] <<std::endl;
     return 0;
   }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.