This is very strange but the program is crashing on array access to the SmartVector. But it only happens every so often so this is going to be a fun bug to track down.
It bails on:
SmartVector.h - SmartVector::operator []
Code:
T &operator[] (const size_t &index)
{
return m_vVector[index];
}
The debugger says that index cannot be evaluated. Nice. So now I have an error that is fragging a variable.
It has something to do with this code:
LaserMgr.cpp - LaserMgr::CheckHits()
Code:
void LaserMgr::CheckHits()
{
for (size_t i = 0;i < m_vLasers.GetSize(); ++i)
{
//If current laser 'slot' is valid
if (m_vLasers[i])
{
//Grab the sprite so we don't have to constantly call GetSpriteMgr()
Sprite *pSprite = X3DGetApp()->GetSpriteMgr()->Get(m_vLasers[i]->SpriteID);
//Grab sprite position and LOCAL/MODEL min/max boundaries
D3DXVECTOR3 vecLaserPos = pSprite->GetPos();
D3DXVECTOR3 vecLaserMin = pSprite->GetMin();
D3DXVECTOR3 vecLaserMax = pSprite->GetMax();
//Transform min/max to WORLD sprite location
float LaserLeft = vecLaserPos.x + vecLaserMin.x;
float LaserTop = vecLaserPos.y + vecLaserMin.y;
float LaserRight = vecLaserPos.x + vecLaserMax.x;
float LaserBottom = vecLaserPos.y + vecLaserMax.y;
//Grab the asteroid manager for use later
AstMgr *pAstMgr = X3DGetApp()->GetAstMgr();
for (size_t j = 0;j < pAstMgr->GetSize(); ++j)
{
//Grab an asteroid
Asteroid *pAst = pAstMgr->Get(j);
//Is it valid?
if (pAst)
{
//Check for collision
int hit = pAst->Collide(LaserLeft,LaserTop,LaserRight,LaserBottom);
if (hit > 0)
{
//We have a collision so remove laser from laser mgr and sprite mgr vectors
X3DGetApp()->GetSpriteMgr()->Remove(m_vLasers[i]->SpriteID);
m_vLasers.Remove(i);
//Let the asteroid manager decide what to do with the doomed asteroid
pAstMgr->Destroy(j);
}
}
}
}
}
}
SpriteMgr.cpp - SpriteMgr::Remove()
Code:
bool SpriteMgr::Remove(const size_t &index)
{
//De-allocate memory
delete m_vSprites[index];
//Remove from vector (only nullifies, does not actually remove)
return m_vSprites.Remove(index);
}
SmartVector.h - SmartVector::Remove()
Code:
virtual bool Remove(const size_t &index)
{
//Check for out of range
if (index > (m_vVector.size()-1))
{
return false;
}
//Nullify current 'slot'
m_vVector[index] = NULL;
//Set cache index to this index (this will be used on next Add() operation)
m_CacheIndex = index;
//Cache value is now valid
m_CacheValid = true;
return true;
}
Yes that's an ugly collision test but it's fast enough for now and I'll improve it later. It doesn't like me removing the lasers from the the laser mgr smart vector after I remove the laser sprite from the sprite mgr smart vector.
Call stack on access violation
> Astroids.exe!SmartVector<Sprite *>::Remove(
const unsigned int & index=) Line 53 + 0x11 bytes C++
Astroids.exe!SpriteMgr::Remove(const unsigned int & index=) Line 64 + 0x17 bytes C++
Astroids.exe!LaserMgr::CheckHits() Line 63 C++
Astroids.exe!LaserMgr::Update(float fTimeDelta=0.019000001) Line 115 C++
Astroids.exe!AstroidsApp::Update(const float fTimeDelta=0.019000001) Line 163 C++
Astroids.exe!D3DApp::EnterMsgLoop() Line 303 + 0x16 bytes C++
Astroids.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * prevInstance=0x00000000, char * cmdLine=0x00151f14, int showCmd=1) Line 119 C++
Astroids.exe!__tmainCRTStartup() Line 589 + 0x35 bytes C
Astroids.exe!WinMainCRTStartup() Line 414 C
Check out index's value in Remove(). It's garbage right there and should not be. Index is just an integer that is actually the j variable in the LaserMgr::CheckHits() nested loop. Very strange. I've highlighted the important portions that I believe are bailing.
Any ideas?