1

I am looking at a unique example here and am trying to understand why his snippet behaves the way it does

// uninitialized mem char test[99999]; // test[0] = 'a'; test[1] = 'b'; test[2] = 'c'; test[3] = 'd'; test[4] = 'e'; test[5] = 'f'; test[6] = 'g'; for (int i = 0; i < 99999; i++) { cout << (&test[i])[i] << endl; } 

In particular, what is happening in memory for the output to skip a character?

output: a c e g .. 
1
  • 1
    & is an address-of operator here. Commented Jul 22, 2016 at 6:46

2 Answers 2

4

This is what is happening: An array is just a contiguous chunk of memory.

&test 

Is getting the address of that index of the starting point of array. Not the value.

When you add [some number], it counts up the number times the size of the data type, in this case each char is a byte.

So when you do

&test[i] 

that means the starting address + i bytes.

when you do

(&test[i])[i] 

You are doing i bytes from the starting address, and then treat that as the starting address and go up i more bytes.

So in your iterations:

(&test[0])[0] // index 0 + 0 = 0 (&test[1])[1] // index 1 + 1 = 2 (&test[2])[2] // index 2 + 2 = 4 (&test[3])[3] // index 3 + 3 = 6 
Sign up to request clarification or add additional context in comments.

3 Comments

This answer suggests that &test[i] means (&test)[i]. It doesn't. It means &(test[i]). There is no &test that [i] gets applied to.
It lets you wrap the entire array dereference in parentheses and count it as the starting pointer. (&(&test[i])[i])[0] , and (&(&(&test[i])[i])[0])[0] give you the same result
@brianxautumn In your final paragraph you have '1+1 = 1'. I did try to edit, but edits have to be at least 6 characters..... you might be able to fix it though.
4

It should become a bit more obvious when you consider what the array indexing is actually doing.

Given an array test, you usually access the nth element of test with test[n]. However, this is actually the equivalent of *(test+n). This is because addition on pointers automatically multiplies the amount you add with the size of the type being pointed to. This means the pointer will then be pointing at the second item in the array if you add one to the pointer, the third item if you add two, and so on.

The code you provide then references that value, so you end up with &(*(test+n)). The reference (&) and the dereference (*) operations then cancel each other out, which means you end up with just test+n.

The code then does another array index on that value, so you end up with (test+n)[n], which again may be written as *((test+n)+n). If you simplify that, you get *(test+n+n), which may be rewritten as *(test+2*n).

Clearly then, if you convert that back to array indexing notation, you end up with test[2*n], which indicates in simple form that you'll be querying every other element of the array.

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.