Reputation: 1471
For instance:
vector<int> something;
//imagine i add some elements to the vector here
int* pointy;
for (int i = 0; i < something.size(); pointy = &something[i++]) {
//do some work with pointy
}
it seems to work and saves me a line but is there any danger of weird bugs popping up down the line because of this?
Upvotes: 1
Views: 237
Reputation: 425
As for me, I like to handle std::vector like this for larger Objects:
std::vector<int*> mynumbers;
//add elements here like this:
int somenumber = 5;
mynumbers.push_back(&somenumber);
for(int i=0;i<elemnts.size();i++)
{
cout << "Element Nr. " << i << ": " << *elements.at(i) << endl;
//modify like this:
*elements.at(i) = 0;
}
The pointer instead of the variable itself is because std::vector handles pointers faster than large objects itself, but for int, this doesn't really make much difference so you can also do it like this:
std::vector<int> mynumbers;
mynumbers.push_back(5);
int* pointy
for(int i=0;i<elemnts.size();i++)
{
pointy = &elements.at(i);
}
Works great for me!
Upvotes: 0
Reputation: 126502
Yes, that is dangerous, as dasblinkenlight pointed out. But there's a simpler way to eliminate this kind of problems.
Write your code for simplicity and readability first. Compressing your loop into the smallest possible number of lines won't add anything in terms of performance, and even if it did, you shouldn't care as long as your profiler doesn't tell you that your loop is a bottleneck.
On the other hand, it will make your code harder to read and, possibly, more prone to bugs (as you've probably noticed).
In C++11, consider using a range-based for
loop:
for (int& p : something)
{
// ...
}
In C++03, consider using std::for_each()
, or a classical loop based on iterators:
for (std::vector<int>::iterator i = something.begin(); i != something.end(); ++i)
{
// use *i to refer to the current pointy
// use (i - something.begin()) to get its index
// ...
}
Upvotes: 6
Reputation: 8400
It is very dangerous, because i
is not unsigned
. It can blow up in some rare cases. :)
Upvotes: 1
Reputation: 7467
Is this safe really depends on what you are after. pointy is going to be a pointer to an element in the vector. This means that if you change the value of pointy, or what it points to be more specific, you are actually changing the content of the vector for that specific element.
Upvotes: 0
Reputation: 726829
This may not be legal, because pointy
is unassigned on the first iteration. If the loop does not dereference pointy
during the initial iteration, it may be OK, but it is not possible to tell without seeing the body of the loop.
Since you are using std::vector
, using iterators would save you another line, because you wouldn't need to declare pointy
. You would be able to determine the offset without i
by subtracting something.begin()
from the current iterator:
for (vector<int>::iterator iter = something.begin() ; iter != something.end() ; ++iter) {
cout << "Item at index " << (iter - something.begin()) << " is " << *iter << endl;
}
Upvotes: 13