Ask a questionAsk a question
 

QuestionVector keeps throwing assert failures

  • Sunday, December 16, 2007 4:11 PMTomb332 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

     

    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 sprites

    vector<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-order

    vector<Sprite*>::iterator siSprite;

    for (siSprite = m_vSprites.begin(); siSprite != m_vSprites.end(); siSprite++)

    if (pSprite->GetZOrder() < (*siSprite)->GetZOrder())

    {

    // Insert the sprite into the sprite vector

    m_vSprites.insert(siSprite, pSprite);

    return;

    }

    }

    // The sprite's z-order is highest, so add it to the end of the vector

    m_vSprites.push_back(pSprite);

    }

    }

    void GameEngine:Big SmilerawSprites(HDC hDC)

    {

    // Draw the sprites in the sprite vector

    vector<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 vector

    RECT 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 it

    rcOldSpritePos = (*siSprite)->GetPosition();

    // Update the sprite

    saSpriteAction = (*siSprite)->Update();

    // Handle the SA_ADDSPRITE sprite action

    if (saSpriteAction & SA_ADDSPRITE)

    // Allow the sprite to add its sprite

    AddSprite((*siSprite)->AddSprite());

    // Handle the SA_KILL sprite action

    if (saSpriteAction & SA_KILL)

    {

    // Notify the game that the sprite is dying

    SpriteDying(*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 vector

    vector<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 vector

    vector<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

  • Friday, October 30, 2009 3:58 AMShawn Eary Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    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

  • Friday, October 30, 2009 2:06 PMWayneAKing Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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