Unsigned integers in C++ for loops

2020-02-08 06:33发布

问题:

I have made some research on Stackoverflow about reverse for loops in C++ that use an unsigned integer instead of a signed one. But I still do NOT understand why there is a problem (see Unsigned int reverse iteration with for loops). Why the following code will yield a segmentation fault?

#include <vector>
#include <iostream>
using namespace std;

int main(void)
{
    vector<double> x(10);

    for (unsigned int i = 9; i >= 0; i--)
    {
        cout << "i= " << i << endl;
        x[i] = 1.0;
    }

    cout << "x0= " << x[0] << endl;

    return 0;
}

I understand that the problem is when the index i will be equal to zero, because there is something like an overflow. But I think an unsigned integer is allowed to take the zero value, isn't it? Now if I replace it with a signed integer, there is absolutely no problem.

Does somebody can explain me the mechanism behind that reverse loop with an unsigned integer?

Thank you very much!

回答1:

The problem here is that an unsigned integer is never negative.

Therefore, the loop-test:

i >= 0

will always be true. Thus you get an infinite loop.

When it drops below zero, it wraps around to the largest value unsigned value.
Thus, you will also be accessing x[i] out-of-bounds.

This is not a problem for signed integers because it will simply go negative and thus fail i >= 0.

Thus, if you want to use unsigned integers, you can try one of the following possibilities:

for (unsigned int i = 9; i-- != 0; )

and

for (unsigned int i = 9; i != -1; i--)

These two were suggested by GManNickG and AndreyT from the comments.


And here's my original 3 versions:

for (unsigned int i = 9; i != (unsigned)0 - 1; i--)

or

for (unsigned int i = 9; i != ~(unsigned)0; i--)

or

for (unsigned int i = 9; i != UINT_MAX; i--)


回答2:

The problem is, your loop allows i to be as low as zero and only expects to exit the loop if i is less than 0. Since i is unsigned, it can never be less than 0. It rolls over to 2^32-1. That is greater than the size of your vector and so results in a segfault.



回答3:

Whatever the value of unsigned int i it is always true that i >= 0 so your for loop never ends.

In other words, if at some point i is 0 and you decrement it, it still stays non-negative, because it contains then a huge number, probably 4294967295 (that is 232-1).



回答4:

The problem is here:

for (unsigned int i = 9; i >= 0; i--) 

You are starting with a value of 9 for an unsigned int and your exit definition is i >= 0 and this will be always true. (unsigned int will never be negative!!!). Because of this your loop will start over (endless loop, because i=0 then -1 goes max uint).