0

Apologies i got frustrated and posted question through mobile without proper details

Consider the following C++ code:

 int arr[2];
    arr[0] = 10;
    arr[1] = 20;
   // cout << &arr;
    for (int i = 0; i < 2; i++)
    {
       cout << &arr + i << "\t\t"<<endl;
    }

    cout << sizeof (arr);

cout in for loop prints following

0x7ffeefbff580 0x7ffeefbff588

which is 8 bytes farther than the first element

My question is why it is 8 bytes further and not 4 bytes if on my machine sizeof(int) is 4?

Faisal Khan
  • 191
  • 1
  • 8
  • 7
    Please post a [mcve]. – R Sahu Jul 01 '19 at 21:44
  • @R Sahu this question is not about coding rather it is about a concept that is why i have not provided any code – Faisal Khan Jul 01 '19 at 21:47
  • 1
    Which compiler, toolset, operating system are you using? – 1201ProgramAlarm Jul 01 '19 at 21:48
  • What makes you think that `sizeof(arr)` is 2? –  Jul 01 '19 at 21:50
  • @1201ProgramAlarm i am using VS 2010 – Faisal Khan Jul 01 '19 at 21:50
  • `why do i get the address of arr[1] which is 8 bytes` Are you measuring pointer's size? Your question is very confusing. What exactly are you doing? – freakish Jul 01 '19 at 21:50
  • @FaisalKhan, it'll be so much easier to figure out where the misunderstanding is with a [mcve]. – R Sahu Jul 01 '19 at 21:51
  • @duskwuff that is because the length of arr is 2 so when i run sizeof(arr) on my machine i get 2 – Faisal Khan Jul 01 '19 at 21:51
  • @FaisalKhan No, that's not what `sizeof` means. –  Jul 01 '19 at 21:53
  • @FaisalKhan ...and that's not what `sizeof(arr)` would return in this case. – Blastfurnace Jul 01 '19 at 21:53
  • 1
    @FaisalKhan it's **extremely** unlikely that `sizeof(arr)` returns `2`. Show us the code. – freakish Jul 01 '19 at 21:54
  • @FaisalKhan `&arr` you are taking a reference to `arr` which of size `8`. And so you "move" in steps of size `8`. Did you mean `&arr[0]`? – freakish Jul 01 '19 at 22:03
  • @freakish Yes my confusion is why &arr[1] is 8 bytes further rather than 4 bytes? array is of type int and int is 4 bytes on my machine so what is the reason that system has allocated it 4*2 bytes? and i assume if array size was 4 then difference of &arr[1] would be 4 * 4 = 16? Why is that? why not just 4 bytes when 4 bytes can hold the int value why allocate it 8 bytes in my case? – Faisal Khan Jul 01 '19 at 22:06
  • 2
    @FaisalKhan This `&arr` returns a pointer to `int[2]` which is a structure of size `8`. **It does not return a pointer to int**. And so `&arr + 1` moves 8 bytes forward. `&arr[1]` **is not** 8 bytes futher. Because what you should do is do `&arr[0]` instead of `&arr` because `&arr[0]` **is a pointer to int** while `&arr` **is not**. They point to the same place but they are of different size, hence pointer arithmetic works differently. – freakish Jul 01 '19 at 22:08
  • @FaisalKhan Your expression `&arr + i` is not what you think it is. Using `(void*)(arr + i)` or `&arr[i]` would be more correct. – Blastfurnace Jul 01 '19 at 22:10
  • @freakish many thanks for your guidance. I just did &arr[1] and i got exactly as i was expecting it to be (4 bytes memory). This is what i was confused about. I am kind of newbie learning about pointers and c++ thanks again :) – Faisal Khan Jul 01 '19 at 22:13
  • 1
    @FaisalKhan When you do `&arr + i` what you are getting is `(&arr) + i`, when you really want `(arr + i)` (no ampersand needed in this case). – Blastfurnace Jul 01 '19 at 22:15
  • @Blastfurnace Many thanks for your comment. Yes i got it now – Faisal Khan Jul 01 '19 at 22:19

1 Answers1

5

Now that you gave us the code we can answer your question.

So the confusing piece is this: &arr + i. This does not do what you think it does. Remember that & takes precedence over +. And so you take address of arr and move it forward i times.

Pointer arithmetic works in such a way that &x + 1 moves the pointer forward by size(x). So in your case what is size(arr)? It is 8 because it is 2-element array of integers (I'm assuming ints are of size 4). And so &arr + 1 actually moves the pointer 8 bytes forward. The exact thing you experience. You don't ask for next int, you ask for next array. I encourage you to play around, for example define arr as int[3] (which is of size 12) and see how the pointer moves 12 bytes forward.

So first solution is to do arr + i without &. We can apply pointer arithmetic to an array in which case it decays to a pointer type int*. Now since int is of size 4 then arr + 1 points correctly to a memory segment 4 bytes forward.

But what I suggest is to stay away from pointer arithmetic and do &arr[i] instead. This does the same thing but IMO is less error prone, less confusing and tells us more about the intent.

freakish
  • 54,167
  • 9
  • 132
  • 169
  • really thanks for your time. This was really helpful. Would you be kind enough to guide me to further resources about memory allocation explained in details? – Faisal Khan Jul 01 '19 at 22:29
  • 1
    @FaisalKhan All we've talked about is a pointer arithmetic and taking references. We haven't touched memory allocation at all. The C++ memory model (and everything else) is a complicated beast. I suppose you can start here: https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – freakish Jul 01 '19 at 22:34