Zdravím, rád bych se zeptal na tuto chybu. Programuju pomocí knížky: "Naučte se programovat počítačové hry za 24 hodin"
C++ až tak extrémně neznám abych si poradil s tímto problémem. Využívá se tam #include <vector> kompilace je v pořádku jen když to spustím tak mi to vypíše chybovou hlášku:
Debug Assertion Failed!
Program <bla bla bla> \include\vector
Line 138
Expresion ("this->Has_container()", 0)
<bla bla bla>
|Přerušit|Opakovat|Přeskočit|
Zde to kolem toho žádku v <vector>:
_Myt& operator--()
{ // predecrement
_SCL_SECURE_VALIDATE(this->_Has_container());
Hledal jsem na netu a všude možně ale našel jsem sice spoustu věcí na tohle téma ale i přesto si nedokážu poradit (např: http://www.daniweb.com/forums/thread170062.html) Furt píší něco o nějaké inkrementaci a podobně ale nevím jak s tím naložit v programu.
Díky moc...
_SCL_SECURE_VALIDATE_RANGE(_Myptr > ((_Myvec *)(this->_Getmycont()))->_Myfirst);
Fórum › C / C++
Chyba s vektorem: _SCL_SECURE_VALIDATE(this->_Has_container());
Používá se to na Sprity(kolize) Zdrojáky dám na "leteckaposta.cz"
Zde (zip):
http://leteckaposta.cz/868661726
Bude to tak lepší jelikož se to používá v jednom ale pro jistotu dám ještě pár navíc které s tím souvisí (můžou)
No každopádně pro zjednodušení tu ukážu hru, která byla k tomu jako příklad. Je to všechno děláno na starším visualku, chybu to nedělá jak je to tam zkompilované, ale jakmile to otevřu v VS 2008 tak to pak blbne to s tím "containerem"... každopádně zde k chybě dojde v okamžiku KOLIZE rakety a meteoritu. (Pro usnadnění hledání chyby). Vše je dělané jako WinApi.
http://leteckaposta.cz/121847013
;) Zkus se na to prosím podívat. Dík
Nepouštěl jsem to, mám linux. Ale podle popisu mně bylo hned jasný odkud vítr fouká. Pohledem do kódu jsem rychle objevil chybu. V souboru GameEngine.cpp v metodě UpdateSprites na řádku 380 se volá erase na vectoru spritů. Jenže erase na vectoru invaliduje všechny iterároty od rušeného prvku (včetně) dál. Lišácké siSprite-- na dalším řádku se tedy chová nedefinovaně. Je možné, že to staré VS skouslo a v novém už to odletí. Každopádně na invalidovaný iterátory se prostě nesmí sahat. Erase proto vrací validní iterátor, který se pak dá použít.
Btw, autorův přístup k c++ je imo (mírně řečeno) špatný. Používá postfixové operátory inc a dec místo prefixových i tam, kde to není třeba. Vůbec nepoužívá konstantí objekty a metody. Některé identifikátory obsahují _ na začátku, což je zakázané normou. Ať přístě raději píše v javě, učetří tím čtenářům nervy a sobě čas.
To ian : Njn tak ta knížka je trochu starší už, ale tak hodí se a + - to funguje :P No sice tohle je hezké tohle mi říkali i jinde že incrementuju iterátor ale problém je že já nevím pořádně co s tím, ty GameEngine.cpp a pod jen "využívám" ale neměním je takže nevím pořádně co s něma a jak to mám opravit, aby to fungovalo. Nedělám s tím nic velkého a něco co by muselo být úplně bezchybné a podobně, stačí mi když to bude fungovat tak proto se ptám: Co přesně s tím? Takže to nemám inkrementovat? Dík
BTW: Ses díval na tu jeho práci která k tomu byla přidaná jak jsem postoval jako poslední že?
Pepa napsal:
To ian : Njn tak ta knížka je trochu starší už, ale tak hodí se a + - to funguje :P No sice tohle je hezké tohle mi říkali i jinde že incrementuju iterátor ale problém je že já nevím pořádně co s tím, ty GameEngine.cpp a pod jen "využívám" ale neměním je takže nevím pořádně co s něma a jak to mám opravit, aby to fungovalo. Nedělám s tím nic velkého a něco co by muselo být úplně bezchybné a podobně, stačí mi když to bude fungovat tak proto se ptám: Co přesně s tím? Takže to nemám inkrementovat?
Princip je takový, že nenecháš for automaticky inkrementovat iterátor, ale děláš to na konci smyčky sám, a to jen v případě, žes z vectoru nemazal. V případě, že jsi erase použil, uložíš do aktálního iterátoru hodnotu, kterou erase vrátil, tu už ale neinkrementuješ. Pokud smazaný prvek byl ve vectoru na posledním místě, erase vrátí vector::end, takže jsi v pohodě.
Zkus to takhle opravit, nebo si vygoogli jak se odebírá z vectoru. Při nejhorším ti sem dám kód.
BTW: Ses díval na tu jeho práci která k tomu byla přidaná jak jsem postoval jako poslední že?
Ano.
To ian :
Místo toho
for (siSprite = m_vSprites.begin(); siSprite != m_vSprites.end(); siSprite++)
{
delete (*siSprite);
m_vSprites.erase(siSprite);
siSprite--;
}
jsem dal:
siSprite = m_vSprites.begin()
while (siSprite !=m_vSprites.end())
{
if ( ??? )
{
delete (*siSprite);
m_vSprites.erase(siSprite);
}
else
{
siSprite++;
}
}
Jenže nevím co dát do toho "if". Dále bych se chtěl zeptat co taky s ifem nad tím:
if (saSpriteAction & SA_KILL)
{
// Notify the game that the sprite is dying
SpriteDying(*siSprite);
// Kill the sprite
delete (*siSprite);
m_vSprites.erase(siSprite);
siSprite--;
continue;
}
tam bych taky měl dát else ale nevím pořádně jak to použít, omlouvám se ale v tomhle se až tak moc nevyznám, jsem rád že mi to vůbec pojede, je to moje maturitní práce a téma už nejde změnit a ve škole nás boužel nic prakticky nenaučili a takovou chybu jsem opravdu nečekal :)
To Anonymní uživatel : Víceméne zachováš ten původní kód (vč. podmínek), upravíš jen drobnosti, jak jsem psal prve. No, nebude tě trápit, tady je kód toho for cyklu a v příloze patch, abys to nemusel opisovat.
for (siSprite = m_vSprites.begin(); siSprite != m_vSprites.end(); /*tady neni nic*/ )
{
// Save the old sprite position in case we need to restore it
rcOldSpritePos = (*siSprite)->GetPosition();
// Update the sprite
saSpriteAction = (*siSprite)->Update();
// 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);
// tohle je dulezite prirazeni
siSprite = m_vSprites.erase(siSprite);
continue;
}
// See if the sprite collided with any others
if (CheckSpriteCollision(*siSprite))
// Restore the old sprite position
(*siSprite)->SetPosition(rcOldSpritePos);
/* inkrement az na konci */
++siSprite;
}
To ian :
Díky moc, funguje to, ale teď mám problém s tím pod tím, s: "void GameEngine::CleanupSprites()" Snažil jsem se to nějak upravit ale bez účinku (vyplivlo to jinačí chybu), proto píšu znova a opět si s tím nevím rady.
původně:
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--;
}
}
Jo a ten GameEngine.cpp, který používám já je "novější" (je tam ještě fce:
// Handle the SA_ADDSPRITE sprite action
if (saSpriteAction & SA_ADDSPRITE)
// Allow the sprite to add its sprite
AddSprite((*siSprite)->AddSprite());
tak jsem to tam přidal)
Zde radši přikládám zdrojáky (je to tam opravené to cos postoval)
http://leteckaposta.cz/152397257
PS: Nevím jak "zacházet" s tím GameEngine.cpp.patch :smile14: (sem to prostě okopíroval a bylo)
Díky za pomoc (a taky vysvětlení)
Ach jo,... ;-D
Pepa napsal:
To ian :
Díky moc, funguje to, ale teď mám problém s tím pod tím, s: "void GameEngine::CleanupSprites()" Snažil jsem se to nějak upravit ale bez účinku (vyplivlo to jinačí chybu), proto píšu znova a opět si s tím nevím rady.
původně:
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--;
}
}
Jako učitel jsem asi selhal, kdybys to opravil tak, jak jsem psal, tak to bude fungovat. I když tady je blbost volat erase při každé iteraci, lepší je zavolat delete na každý prvek toho vectoru a pak dát vector::clear:
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.clear();
}
Pak ses ještě přehlíd při tom yank/put (rozuměj copy/paste ;), kód na řádcích 395-398 tam máš dvakrát, tak ho smaž.
To ian : To s tím přehlídnutím, tak to jsem si pak opravil ale už jsem to na tu leteckou poštu dal, ale našel a opravil sem si to takže to v pohodě, měl jsem problém jen s tím CleanUpSprites() ;) Díky moc, jako učitel si neselhal spíš já tady tápu ve tmě ;)
a jinak díky moc, funguje to ;) zachránil jsi mě
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Moderátoři diskuze