Jake Freelander
Jake Freelander

Reputation: 1471

Is this legal use of a for loop?

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

Answers (5)

theCNG27
theCNG27

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

Andy Prowl
Andy Prowl

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

cubuspl42
cubuspl42

Reputation: 8400

It is very dangerous, because i is not unsigned. It can blow up in some rare cases. :)

Upvotes: 1

Philip Stuyck
Philip Stuyck

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

Sergey Kalinichenko
Sergey Kalinichenko

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

Related Questions