Vector keeps throwing assert failures
Ok i have a very simple game engine that i made using VC++ 2003 which ran perfectly fine. Recently i moved over to VC++ 2008 and now every time the program is run it creates assert faliures withing 2 seconds of the vector in it being used.
Here is all the relevant source code.
BOOL GameEngine::CheckSpriteCollision(Sprite* pTestSprite)
{
// See if the sprite has collided with any other spritesvector<Sprite*>::iterator siSprite;
for (siSprite = m_vSprites.begin(); siSprite != m_vSprites.end(); siSprite++){
// Make sure not to check for collision with itself if (pTestSprite == (*siSprite)) continue; // Test the collision if (pTestSprite->TestCollision(*siSprite)) // Collision detected return SpriteCollision((*siSprite), pTestSprite);}
// No collision return FALSE;}
void
GameEngine::AddSprite(Sprite* pSprite){
// Add a sprite to the sprite vector if (pSprite != NULL){
// See if there are sprites already in the sprite vector if (m_vSprites.size() > 0){
// Find a spot in the sprite vector to insert the sprite by its z-ordervector<Sprite*>::iterator siSprite;
for (siSprite = m_vSprites.begin(); siSprite != m_vSprites.end(); siSprite++) if (pSprite->GetZOrder() < (*siSprite)->GetZOrder()){
// Insert the sprite into the sprite vectorm_vSprites.insert(siSprite, pSprite);
return;}
}
// The sprite's z-order is highest, so add it to the end of the vectorm_vSprites.push_back(pSprite);
}
}
void
GameEngine:
rawSprites(HDC hDC)
{
// Draw the sprites in the sprite vectorvector<Sprite*>::iterator siSprite;
for (siSprite = m_vSprites.begin(); siSprite != m_vSprites.end(); siSprite++)(*siSprite)->Draw(hDC);
}
void
GameEngine::UpdateSprites(){
// Update the sprites in the sprite vectorRECT rcOldSpritePos;
SPRITEACTION saSpriteAction;
vector<Sprite*>::iterator siSprite;
for (siSprite = m_vSprites.begin(); siSprite != m_vSprites.end(); siSprite++){
// Bail if sprite is not valid if((*siSprite) == NULL){ continue;}
// Save the old sprite position in case we need to restore itrcOldSpritePos = (*siSprite)->GetPosition();
// Update the spritesaSpriteAction = (*siSprite)->Update();
// Handle the SA_ADDSPRITE sprite action if (saSpriteAction & SA_ADDSPRITE) // Allow the sprite to add its spriteAddSprite((*siSprite)->AddSprite());
// Handle the SA_KILL sprite action if (saSpriteAction & SA_KILL){
// Notify the game that the sprite is dyingSpriteDying(*siSprite);
// Kill the sprite delete (*siSprite);*siSprite = NULL;
m_vSprites.erase(siSprite);
siSprite--;
continue;}
// See if the sprite collided with any others if (CheckSpriteCollision((*siSprite))) //<- Normally Crashes Here // Restore the old sprite position(*siSprite)->SetPosition(rcOldSpritePos);
}
}
void
GameEngine::CleanupSprites(){
// Delete and remove the sprites in the sprite vectorvector<Sprite*>::iterator siSprite;
for (siSprite = m_vSprites.begin(); siSprite != m_vSprites.end(); siSprite++){
delete (*siSprite);m_vSprites.erase(siSprite);
siSprite--;
}
}
Sprite* GameEngine::IsPointInSprite(
int x, int y){
// See if the point is in a sprite in the sprite vectorvector<Sprite*>::reverse_iterator siSprite;
for (siSprite = m_vSprites.rbegin(); siSprite != m_vSprites.rend(); siSprite++) if (!(*siSprite)->IsHidden() && (*siSprite)->IsPointInside(x, y)) return (*siSprite); // The point is not in a sprite return NULL;}
All Replies
I can not readily see where the crash is; however, I would suggest trying a forward facing iterator for the method GameEngine::IsPointInSprite. It seems like I tried using reverse_iterators before and had problems with my iterator stopping in weird places. It "could" be that VS2008 Express is allowing the siSprite iterators to become NULL before m_vSprites.rend() is ever reached [Just a wild guess.]
Also, I understand that you are probably trying to use iterators for efficiency reasons instead of the standard vector [] operator, but I can't think of any legitimate reason why the [] operator would be any slower than the ::iterator for a vector. Unless VS 2008 Express provides a very poor implemenation of std::vector the [] operator should return in O(1) time because vectors are homogeneous in nature. Given this understanding that [] "should" run just as fast as as ::iterator, I might even go as for as tranforming my iteration code to index based loops.
e.x.:
Sprite * mySpritePtr;
for (unsigned int i = 0; i < m_vSprites.size(); i++) {
mySpritePtr = m_vSprites[i];
if (!(mySpritePtr->IsHidden()) && (mySpritePtr->IsPointInside(x,y)) {
return (mySpritePtr);
}
return NULL;
}
I don't "think" you will loose any efficiency by switching to the [] operator and the code should be slightly easier to troubleshoot and maintain.
With Respect,
Shawn- Shawn -
Are you aware that you replied to a post which is almost two years old?
I hope Tomb332 isn't still waiting for a solution. ;-)
- Wayne

