Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
276 views
in Technique[技术] by (71.8m points)

c++ - How does *(&arr + 1) - arr give the length in elements of array arr?

#include <iostream>
using namespace std;

int main() { 
   int  arr[5] = {5, 8, 1, 3, 6};
   int len = *(&arr + 1) - arr;
   cout << "The length of the array is: " << len;
   return 0;
} 

For the code above, I don't quite understand what these two pieces of codes are doing:

*(&arr + 1) 

and

*(&arr)
&arr

Could someone explains? Because when I run the following two codes, I get the same output for the following:

&arr (I think this point to the address of the first element of arr)

*(&arr) then I don't quite understand what this do, what does the symbol * do to &arr (i.e. to the address here)?, because the two outputs are the same when I run them

and finally what is it exactly happening when an integer say 1 is added to the address by this code here: &arr + 1

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is a mine field, but I'll give it a try:

  • &arr returns a pointer to an int[5]
  • + 1 steps the pointer one int[5]
  • *(&arr + 1) dereferences the result back to an int(&)[5]
    I don't know if this causes undefined behavior, but if it doesn't, the next step will be:
  • *(&arr + 1) - arr does pointer arithmetics after the two int[5]'s have decayed to int pointers, returning the diff between the two int pointers, which is 5.

Rewritten to make it a bit clearer:

int  arr[5] = {5, 8, 1, 3, 6};

int (*begin_ptr)[5] = &arr + 0;     // begin_ptr is a  int(*)[5]
int (*end_ptr)[5]   = &arr + 1;     // end_ptr is a    int(*)[5]

// Note:
//       begin_ptr + 1        ==  end_ptr
//       end_ptr - begin_ptr  ==  1

int (&begin_ref)[5] = *begin_ptr;   // begin_ref is a  int(&)[5]
int (&end_ref)[5]   = *end_ptr;     // end_ref is a    int(&)[5]   UB here?

auto len = end_ref - begin_ref; // the array references decay into int*
std::cout << "The length of the array is: " << len << '
'; // 5

I'll leave the question if it's UB or not open but referencing an object before the referenced storage has been allocated does look a bit suspicious.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...