[SFML] [C++] vector subscript out of range

Started by
18 comments, last by Doug Rogers 8 years, 7 months ago

	//Enemy projectile collide

	collideCounter = 0;
	
	for (iter2 = projArray.begin(); iter2 != projArray.end(); iter2++){
		collideCounter2 = 0;

		for (iter3 = projArray.begin(); iter3 != projArray.end(); iter3++){
			if (projArray[collideCounter].rect.getGlobalBounds().intersects(enemy.enemyArray[collideCounter2].enemySprite.getGlobalBounds()))
			{
				std::cout << "COLLIDE" << std::endl;
			}

			collideCounter2++;
		}
		collideCounter++;
	}

Seems to be the 2nd for loop giving me the subscript out of range. I have no idea where to start looking, it could be the amount of bullets that are being spawned because if I click my mouse fast, it will only spawn a few bullets instead of like 8-10 so maybe its conflicting with the collision but I'm not sure, only this part of the code is giving me the error.

Advertisement
On your specific error, probably you are expecting to iterate over enemy.enemyArray for the inner loop rather than projArray.

If that was a typo in your post but different in your actual code, stop that in the debugger when the error occurs and look at the values of collideCounter and collideCounter2. You should find that one of them exceeds the length of the array they are being used on, either projArray or enemyArray.


As for the general condition, I sure hope you have a small number of items in those arrays. That kind of all-to-all comparison results in dangerously fast computational growth. Most systems build spatial trees and only compare the immediate neighbors.

On your specific error, probably you are expecting to iterate over enemy.enemyArray for the inner loop rather than projArray.

If that was a typo in your post but different in your actual code, stop that in the debugger when the error occurs and look at the values of collideCounter and collideCounter2. You should find that one of them exceeds the length of the array they are being used on, either projArray or enemyArray.


As for the general condition, I sure hope you have a small number of items in those arrays. That kind of all-to-all comparison results in dangerously fast computational growth. Most systems build spatial trees and only compare the immediate neighbors.

wow thanks a lot! can't believe I was overlooking that this whole time

We are sooo good at reading what we think rather than what it says smile.png

Why are you using iterators in your for loops, in addition to counters? Just dereference the iterator...

Or better yet, if your compiler supports C++11, use the new range-for construct which eliminates these kinds of issues entirely smile.png


for (const auto& item : myArray)
{
  // do some calculation with item - which is basically "myArray[i]"
}
I don't have experience with this:

for (const auto& item : myArray)
{
  // do some calculation with item - which is basically "myArray[i]"
}


But...

Why are you using iterators in your for loops, in addition to counters? Just dereference the iterator...


	//Enemy projectile collide
	
	for (iter2 = projArray.begin(); iter2 != projArray.end(); ++iter2){

		for (iter3 = enemy.enemyArray.begin(); iter3 != enemy.enemyArray.end(); ++iter3){
			if (*iter2.rect.getGlobalBounds().intersects(*iter3.enemySprite.getGlobalBounds()))
			{
				std::cout << "COLLIDE" << std::endl;
			}

		}
	}

I don't have experience with this:






for (const auto& item : myArray)
{
  // do some calculation with item - which is basically "myArray[i]"
}


This code basically is saying "for each item in myArray" - where "item" is a const ref of whatever the element type of myArray is.

It is the functional equivalent of:

const auto endIter = end(myArray);
for (auto iter = begin(myArray); iter != endIter; ++iter)
{
  const auto& item = *endIter;
  // do stuff here
}
"begin" and "end" are non-member functions that call "begin" and "end" as members on containers, but are non-members themselves so they can be specialized for compile-time arrays so you can use the ranged-for syntax on them:


int myArray[20];
// fill myArray
for (const auto& item : myArray)
{
  // do stuff with the items
}
This won't work, because the compiler has no way to get the size of the array:

int* myArray = new int[size];
// fill myArray
for (const auto& item : myArray) // compile error!
{
  // do stuff with the items
}
delete [] myArray;
Which is one reason it is typically preferred to use std::array and std::vector over raw C arrays.

Thanks. Since I don't have experience with it, I couldn't use it as an example. It appears to be the better way though.

Why are you using iterators in your for loops, in addition to counters? Just dereference the iterator...

Or simpler still, iterators can be used like this....


	if(someIterator.hasNext()){
	     while(someIterator.hasNext()){
		  functionDoingSomeStuff( someIterator.next(), someIterator.previousIndex()  );// Parameters:get object referenced with its index
	    }
        }

Though in Java i expect the principle to be applicable in C++

can't help being grumpy...

Just need to let some steam out, so my head doesn't explode...


Though in Java i expect the principle to be applicable in C++

Nope. There does not exist anything like hasNext or conversion between iterators and indexes (previousIndex) in C++

This topic is closed to new replies.

Advertisement