0

Is there any way to use foreach in pointers? For example

int numbers[] = {1,2,3,4};

for (int& n : numbers) {
    n *= 2;
}

this works fine but if I change numbers with int pointer foreach gives error.

int* numbers = new int[4];

*numbers =  1;
*(numbers + 1) =  2;
*(numbers + 2) =  3;
*(numbers + 3) =  4;

for (int& n : numbers) {
    n *= 2;
}
 
delete[] numbers; 

Aren't they both basically the same thing? I'm allocating 16 bytes of space for both, and it's obvious where they'll end up. Why does it work fine in the above example but not in the other example?

4
  • 1
    Pointers aren't arrays. The language supports range-for on native arrays. No such thing exists (or could) on raw pointers. The error, inconveniently omitted from your post, (hint: when you have questions about errors always include the verbatim error message in your post) should have said as much. Commented Feb 5, 2022 at 12:03
  • However, when I define an array like (int numbers[];), for example, the numbers variable holds the address of the first value. It also holds the value of a variable when I define it as a pointer. I don't claim to be exactly the same, but I'm confused in which parts it differs. Commented Feb 5, 2022 at 12:07
  • As I said. Pointers aren't arrays. When used in an expression context, the id of a native array converts to a temporary pointer-to-first-element. That is genuinely their only relationship. Ranged-for does not work on raw pointers. Thankfully it is trivial to code a pointer loop to accomplish the same feat, assuming you know the magnitude (which you do in your example: 4). Commented Feb 5, 2022 at 12:30

1 Answer 1

4

A range-based for loop only works on containers where the compiler can work out the container's starting and ending iterators, either via:

  • non-static begin()/end() methods

  • overloads of the standalone std::begin()/std::end() functions

  • in the case of a fixed array, via pointer arithmetic using the array's known size.

A pointer to an array does not satisfy that requirement. Although the pointer itself can act as the starting iterator, there is no way for the loop to know how many elements are in the array to determine its ending iterator.

So, you will have to use a traditional for loop instead:

int* numbers = new int[4];

numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;

for (int i = 0; i < 4; ++i) {
    numbers[i] *= 2;
}

delete[] numbers; 

Or, you can make your own iterators:

int* numbers = new int[4];

numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;

int *iter = numbers, *end = numbers + 4;
while (iter != end) {
    *iter++ *= 2;
}

delete[] numbers; 
Sign up to request clarification or add additional context in comments.

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.