Click to See Complete Forum and Search --> : why is this for loop not working?


lab1
January 19th, 2007, 10:21 AM
Hello all,

I have the following for loop. When size() returns a 0, the for condition should be -1 and it should not go into the for loop, correct?

for(vector<CNodeData*>::size_type i = 0; i < GetInputRVRs().size() - 1; i++)
{

for some reason when size() returns 0, the for loop is still executed. What am I doing wrong here?

Thanks!

panzer2k4
January 19th, 2007, 10:34 AM
size_type is actually an unsigned int. When the size is 0, you are testing "i < -1". Unfortunately, since it's an unsigned in, "-1" is treated as INT_MAX which means you're actually testing "i < INT_MAX" -> hence it runs a ridiculous number of times!

What you actually want to test for is:

for(vector<CNodeData*>::size_type i = 0; i < GetInputRVRs().size(); i++)

Note the lack of the "- 1". Convince yourself that this is correct. Alternatively, you can do:

for(vector<CNodeData*>::size_type i = 0; i <= GetInputRVRs().size() - 1; i++)

GNiewerth
January 19th, 2007, 10:54 AM
size_type is actually an unsigned int. When the size is 0, you are testing "i < -1". Unfortunately, since it's an unsigned in, "-1" is treated as INT_MAX which means you're actually testing "i < INT_MAX" -> hence it runs a ridiculous number of times!

What you actually want to test for is:

for(vector<CNodeData*>::size_type i = 0; i < GetInputRVRs().size(); i++)

Note the lack of the "- 1". Convince yourself that this is correct. Alternatively, you can do:

for(vector<CNodeData*>::size_type i = 0; i <= GetInputRVRs().size() - 1; i++)

Thatīs true if he wants to iterate over all elements in the vector. Maybe he wants to leave out the last one, so he added the -1 to the code. Nevertheless, an excellent clue!

Regards,
Guido

MrViggy
January 19th, 2007, 04:08 PM
Thatīs true if he wants to iterate over all elements in the vector. Maybe he wants to leave out the last one, so he added the -1 to the code. Nevertheless, an excellent clue!

Regards,
Guido
If that's the case, then:
vector<CNodeData*>::iterator endIter = GetInputRVRs().end();
--endIter;
for (vector<CNodeData*>::iterator iter = GetInputRVRs().begin(); iter != endIter; ++iter)
{
...
}
Or:
vector<CNodeData*>::reverse_iterator iter = GetInputRVRs().rbegin();
++iter;
for (; iter != GetInputRVRs().rend(); ++iter)
{
...
}
:D

Viggy

Zaccheus
January 19th, 2007, 04:42 PM
What you actually want to test for is:

for(vector<CNodeData*>::size_type i = 0; i < GetInputRVRs().size(); i++)
Exactly.
:thumb:

Alternatively, you can do:

for(vector<CNodeData*>::size_type i = 0; i <= GetInputRVRs().size() - 1; i++)
Doesn't that just cause the same problem?

If size == 0, i <= 0xFFFFffff will still not work.


Also, wouldn't Viggy's code malfunction if size == 0 ?

exterminator
January 20th, 2007, 12:14 PM
Doesn't that just cause the same problem? If size == 0, i <= 0xFFFFffff will still not work. Also, wouldn't Viggy's code malfunction if size == 0 ?Also, wouldn't Viggy's code malfunction if size == 0 ?Yes, you are correct, in both cases...

Alternatively, can use for_each.. somewhat like this:#include<vector>
#include<algorithm>

template<typename T>
struct DoSomething{
void operator()(const T& t) const
{
//do something with t
}
void operator()(T& t) const
{
//do something with t
}
};

int main()
{
const std::vector<int> vec;
std::vector<int> vec2;
//fill vec/vec2 or do whatever
std::for_each(vec.begin(), vec.end(), DoSomething<int>());
std::for_each(vec2.begin(), vec2.end(), DoSomething<int>());
}I considered that the last element does not need any special treatment... if that's the case the above can be put inside an if-block if(size>0) and then used (of course with for_each working till .end()-1). Hope it helps...