# Easy iteration using a pointer

Page 1 of 1

## 5 Replies - 2393 Views - Last Post: 20 June 2012 - 02:31 PM

### #1 pokiaka

Reputation: 10
• Posts: 76
• Joined: 05-August 11

# Easy iteration using a pointer

Posted 20 June 2012 - 11:58 AM

Let's say I have an array/vector of integers.
And I want to pass through them all, set a value, and print them in console.

Take this for example:
```vector<int> my_ints(100);
for (size_t i = 0; i < my_ints.size(); ++i)
{
my_ints[i] = i;
cout << my_ints[i] << endl;
}
```

I find it pretty unpleasant to write my_ints[ i ] over and over again so I thought of just pointing to it like so:

```for (size_t i = 0; i < my_ints.size(); ++i)
{
int & current = my_ints[i]; //Use a pointer to point to it

current = i; //Using 'current' instead of 'my_ints[i]'
cout << current << endl;
}
```

Obviously, at least for me, this is much more readable. in longer code it's very beneficial.

But the question comes to mind, does this approach use unnecessary memory/CPU resources? etc.
and in general - would this count as a good programming habit?

Thank you.

Is This A Good Question/Topic? 0

## Replies To: Easy iteration using a pointer

### #2 ishkabible

• spelling expret

Reputation: 1676
• Posts: 5,836
• Joined: 03-August 09

## Re: Easy iteration using a pointer

Posted 20 June 2012 - 12:44 PM

those 2 snippets we likely generate the same code.

if you find the array access notation you might consider iterators

```for(auto i = my_ints.begin(); i != my_ints.end(); ++i) {
*i = i - my_ints.begin();
cout<<*i<<endl;
}

```

note: that requires that 'auto' keyword is allowed by your compiler, if not see about turning C++11 features on.

or you can use std::for_each with a lambda function(another C++11 feature)

```std::for_each(my_ints.begin(), my_ints.end(), [&](int& i) {
//...what ever in here, 'i' is like 'current' here
});

```

### #3 NickDMax

Reputation: 2254
• Posts: 9,245
• Joined: 18-February 07

## Re: Easy iteration using a pointer

Posted 20 June 2012 - 01:21 PM

Actually your method is bound to cause you troubles! the standard library has a nasty habit of moving memory around on you. For example take this little test code:
```#include <iostream>
#include <vector>

using namespace std;

int main() {
vector<int> myVect;

myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;

return 0;
}
```

the output for me is:
```> "C:\CProjects\Forum Help\stdvectorMoves.exe "
0x5446cc
0x541e84
0x541e94
0x541e94
0x541eac
0x541eac
```

Notice how the address of myVect[1] changes! This is because when the vector was resized a new buffer was created, and the vector copied over to the new buffer.

Long story short -- it is not generally safe to access a member of a vector via a pointer!

Your idea however is actually sound! In general you can avoid lookups into a data set which *might* offer some efficiency over doing the lookup again and again.

So with vectors rather than a pointer, you can use an iterator.
```#include <iostream>
#include <vector>

using namespace std;

int main() {
vector<int> myVect;

myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
int counter = 0;
for(vector<int>::iterator i = myVect.begin(); i != myVect.end(); i++, counter++) {
*i = counter;
}

for(vector<int>::iterator i = myVect.begin(); i != myVect.end(); i++) {
cout << *i << endl;
}

return 0;
}
```

Of course now you have to write all these long std::vector<std::string>::interator kind of variable declarations and they get a little irritating.

In C++11 you can use auto to make things easier:
```     for(auto i = myVect.begin(); i != myVect.end(); i++) {
cout << *i << endl;
}
```

Of course you could always have used the std::for_each:
```#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Counter {
int value;
public:
Counter() : value(0) { }
void operator()(int& in) { in = value++; }
};

void printVectIntItem(int& in) { cout << in << endl; }

int main() {
vector<int> myVect;

myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;

Counter counter;
for_each(myVect.begin(), myVect.end(), counter);
for_each(myVect.begin(), myVect.end(), printVectIntItem);

return 0;
}
```

While this avoids having to write out a lot of vector<>::iterator declarations, and avoids the dereferencing (*i), you NOW have to write fuctors and special purpose functions.

Again C++11 to the rescue!
```#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
vector<int> myVect;

myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;
myVect.push_back(1);
cout << &myVect[1] << endl;

int counter = 0;
for_each(myVect.begin(), myVect.end(), [&](int& i) { i = counter; counter++;});
for_each(myVect.begin(), myVect.end(), [](const int& i) { cout << i << endl; });

return 0;
}
```

Now as neat as this is, we actually came full circle - this program suffers from the same dangers as your initial idea! If the vector myVect is resized inside of the lambda then the address of the current element i may change... so did we really solve anything? Not really - the safe thing (if the vector may change size inside your loop) is still to use the iterators directly rather than try to reference them away.

### #4 sepp2k

• D.I.C Lover

Reputation: 2277
• Posts: 3,507
• Joined: 21-June 11

## Re: Easy iteration using a pointer

Posted 20 June 2012 - 01:29 PM

ishkabible, on 20 June 2012 - 09:44 PM, said:

or you can use std::for_each with a lambda function(another C++11 feature)

```std::for_each(my_ints.begin(), my_ints.end(), [&](int& i) {
//...what ever in here, 'i' is like 'current' here
});

```

There's no need to use for_each in C++11 when the code to be executed is known at write time. You can just use the new syntax for for-loops:

```for(int& i : my_ints) {
// ...
}

```

NickDMax, on 20 June 2012 - 10:21 PM, said:

So with vectors rather than a pointer, you can use an iterator.[code]#include <iostream>

Using an iterator instead of a pointer does not help you at all when inserting elements into vector. Changing the size of a vector invalidates all iterator, just like it does with pointers. So the only safe way to iterate over a vector while adding to it is via indices.

That said, you usually don't add to a vector while iterating over it.

This post has been edited by sepp2k: 20 June 2012 - 02:30 PM

### #5 NickDMax

Reputation: 2254
• Posts: 9,245
• Joined: 18-February 07

## Re: Easy iteration using a pointer

Posted 20 June 2012 - 01:46 PM

sepp2k, on 20 June 2012 - 04:29 PM, said:

NickDMax, on 20 June 2012 - 10:21 PM, said:

So with vectors rather than a pointer, you can use an iterator.[code]#include <iostream>

Using an iterator instead of a pointer does not help you at all when inserting elements into vector. Changing the size of a vector invalidates all iterator, just like it does with pointers. So the only safe way to iterate over a vector while adding to it is via indices.

That said, you usually don't add to a vector while iterating over it.

You know, now that you mention it I am pretty sure your right. I should have looked into that, I think it was tickling the back of my mind as I wrote. oh well, I will get back into the swing of things eventually.

### #6 ishkabible

• spelling expret

Reputation: 1676
• Posts: 5,836
• Joined: 03-August 09

## Re: Easy iteration using a pointer

Posted 20 June 2012 - 02:31 PM

seep2k: Yes, a range based for loop is even better, thanks for reminding us!

there is a minor caveat if you're using however. VC++10 doesn't support range based for loops, VC++12 beta does and VC++12 will but currently it's VC++ doesn't support it.

also even though I didn't do it, you should us begin(my_ints) instead of my_ints.begin(). It makes no difference if you know you will always be using a vector but if you're writing generic code then it's preferable becuase it will work on containers and things that are not containers.

This post has been edited by ishkabible: 20 June 2012 - 02:32 PM