As already stated by DeiDei, this is the result of unlucky mixing of signed and unsigned integer.
Please note, std::vector::size()
returns size_t
.
Depending on platform, this is usally a 32 bit or 64 bit unsigned
. (size_t
has the same number of bits like void*
.)
In the 1st sample:
for(int i = 0; i<luck.size() - k; i++) sum+=luck[i]; //RUNTIME ERROR
the following values occur:
luck.size()
: (size_t)5
k
: (int)10
luck.size() - k
: (size_t)0xFFFFFFFFFFFFFFFB (assuming 64 bit size)
The comparison of i < luck.size() - k
promotes i
to size_t
as well. So, iteration does not stop at 5. Hence, in the 1st sample code, you get an out-of-bound access in the loop.
In the 2nd sample:
int boundary = luck.size() - k; // HERE
for(int i = 0; i<boundary; i++) sum+=luck[i]; //CONDITION CHANGE
the value is converted to int
again.
int boundary = luck.size() - k;
: (int)-5
This results simply in no iteration of loop.
Demo:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> luck;
int k = 10;
int sum = 0;
for(int i = 0; i<5; i++) luck.push_back(i);
// trying 2nd version:
std::cout << "2nd version:\n";
int boundary = luck.size() - k; // HERE
for(int i = 0; i<boundary; i++) {
std::cout << "i: " << i << '\n';
sum+=luck[i]; //CONDITION CHANGE
}
std::cout << "sum: " << sum << std::endl;
// trying 1st version
std::cout << "1st version:\n";
sum = 0;
for(int i = 0; i<luck.size() - k; i++) {
std::cout << "i: " << i << '\n';
sum+=luck[i]; //RUNTIME ERROR
}
std::cout << "sum: " << sum << std::endl;
// done
return 0;
}
Output:
2nd version:
sum: 0
1st version:
i: 0
i: 1
i: 2
i: 3
i: 4
i: 5
i: 6
i: 7
i: 8
i: 9
i:
Note:
The output of sum
doesn't happen. The application simply dies without further notification. This is one kind how undefined behavior may manifest. A segmentation fault is another.
Live Demo on coliru