Reputation: 25
The problem is that when i do "for(int i = 0; i < vector.size() - 1; i++)", it gives me a "vector subscript out of range" error. However if I put the vector.size() - 1 in a variable, it works. Is this a glitch or am I just missing something?
this works:
int sizePos = positionsX.size() - 1;
for (int i = 0; i < sizePos; i++) {
if (snake.getX() == positionsX[i] && snake.getY() == positionsY[i]) {
gameOver = true;
std::cout << as << std::endl;
as++;
}
if (apple.getX() == positionsX[i] && apple.getY() == positionsY[i]) {
apple.eat();
}
}
and this does not:
for (int i = 0; i < positionsX.size() - 1; i++) {
if (snake.getX() == positionsX[i] && snake.getY() == positionsY[i]) {
gameOver = true;
std::cout << as << std::endl;
as++;
}
if (apple.getX() == positionsX[i] && apple.getY() == positionsY[i]) {
apple.eat();
}
}
Upvotes: 1
Views: 128
Reputation: 311028
You did not point out what means "does not work" that is in which case the code does not work.
Nevertheless answering your question
Is there a bug when using for loop with vectors?
I'll say that the code indeed has bugs.
First of all the size of vectors is defined as unsigned integral type. The type int
in general can not accomodate all values of the unsigned integral type.
In this expression
positionsX.size() - 1
there is used the arithmetic of unsigned integral types. That is the expression positionsX.size() - 1
is converted to the unsigned integral type and will be equal to the maximum value for the type provided that positionsX.size()
is equal to 0. That is the expression in fact evaluates as
static_cast<decltype( positionsX )::size_type>( positionsX.size() - 1 );
For example for an empty vector you can get the following result
#include <iostream>
#include <vector>
int main()
{
std::vector<int> positionsX;
auto size = static_cast<decltype( positionsX )::size_type>( positionsX.size() - 1 );
std::cout << size << '\n';
}
The console output is
18446744073709551615
In the first case when an intermediate variable is used
int sizePos = positionsX.size() - 1;
the result of the expression
positionsX.size() - 1
can be truncated to fit an object of type int
and corresponding indices will be valid (though the range can be in whole invalid that is it can be less than the actual range).
Thus your problem is that you are using the type int
instead of the original type
decltype( positionX )::size_type
Also the loops omit the last element of the vector.
The correct loop can look the following way
for (decltype( positionX )::size_type i = 0; i < positionsX.size(); i++) {
//...
}
Or at least you should use the type size_t as the type of the variable i
(though the first variant is more correct)
for ( size_t i = 0; i < positionsX.size(); i++) {
//...
}
Upvotes: 2
Reputation: 234715
positionsX.size()
is an unsigned
type. If it's zero then subtracting 1 from it gives you the maximum value of the unsigned type due to wrap-around and the fact that the expression is evaluated in unsigned arithmetic!
Use
for (std::size_t i = 0; i + 1 < positionsX.size(); i++) {
instead, nothing that this will always omit the final element in the vector. If you don't want that then drop the + 1
.
Upvotes: 7
Reputation: 2371
If positionsX
vector is empty, then positionsX.size() - 1
evaluates to size_t(-1)
which is a very big positive value.
When converted to int
, as in your first snippet, that value would likely turn back into '-1'. And the loop body is skipped.
When used in comparision i < positionsX.size() - 1
, the compiler converts i
to unsigned size_t
and the comparision yields true. The loop body is executed. And it attempts accessing positionsX[0]
which isn't there...
Upvotes: 2