Turbodiesel Racing on tehty C/C++:lla käyttäen SDL ja SDL_ttf kirjastoja grafiikan ja tekstin piirtoon. Nyt kuitenkin tapahtui jotain mihin edes #C++.fi väki ei löytänyt vastausta:
Peli käynnistyy ja toimii täysin normaalisti. Kun peli sammuu, se toimii juuri niinkuin pitääkin main()-funktion loppuun asti. Sen jälkeen se kaatuu - Dev-C++:n debug-toiminnon mukaan syynä "Access Violation (Segmentation Fault)". Virheessä kummaksuttaa se, että se kaatuu vasta main()-funktion jälkeen.
Käänsin koodin sekä Dev-C++:lla (Mingw) ja VC++ 6.0:lla, mutta kummankin exe kaatui sen sammumisen jälkeen.
Dll:t olen päivittänyt ja ne ovat varmasti uusimmat versiot mitä löytyy.
Laitettuani pelin jakoon, se kaatui muillakin aiheuttaen yleensä Windowsin vakion "lähetä virheraportti kohteelle microsoft..."
Ohessa lähdekoodit pastena, zippinä, ja käännetty peli windowsille (ilmeisesti toimii myös Linuxilla emulaattorin kanssa) Lähdekoodit pitäisi kääntyä Linuxille ilman ongelmia.
Paste: http://mureakuha.com/paste/?
Sorsat paketissa:
http://www.geocities.com/bigenergized/
Windows binary
http://www.geocities.com/bigenergized/TDR_B5.zip
Yksinkertasesti, sun ohjelmassa taitaa olla muistivuoto. Tarkista osoittimet, käytä hans boehm -roskienkeruuta jos haluat päästä kyseisistä ongelmista eroon.
Yksi kummia virheitä aiheuttava on se, että kirjoittelee muistiin väärään paikkaan. Sekin toisinaan näkyy tuollaisena virheenä vasta myöhemmin. Ja tosiaan kaikki muistin varaukset ja vapautukset kannattaa käydä läpi. Koodia tuossa on niin paljon, etten ala itse sitä debugata.
tilemap = new unsigned short*[MapWidth]; int i = 0; while(i < MapWidth) { tilemap[i] = new unsigned short[MapHeight]; i++; }; int luettu = 0; for(int y = 0; y < MapWidth; ++y) { for(int x = 0; x < MapHeight; ++x) { myfile >> tilemap[x][y]; luettu++; } }
Hieman jäi hämmentämään tuo for-looppi. Onkos x:n ja y:n paikat menny sekasin?
Ainoa muu mahdollisen muistivuotoon johtavan kohdan löysin riviltä 567 alkavasta funktiosta(Map::GetTile). Jos edellä mainittu ei auta niin tarkista, mitä arvoja sen funktion käsittelemät muuttujat saavat.
Käsittääkseni dekonstruktorit suoritetaan main()-funktion return käskyssä, joten niitä voi myös kokeilla kommentoida pois.
Edit: Tutkin kenttätiedostoa ja havaitsin, että olet asettanut kentän leveydeksi 45, vaikka tietoa on vain 40:lle.
Edit2: Haaa! Tiesin, että vika on dekonstruktoreissa! :)
Edellä mainitsemani virheet on hyvä korjata, mutta itse sulkemisessa tapahtuva virhe aiheutuu Pinta.h tiedossa sijaitsevasta Pinta-luokan destruktorin ainokaisesta rivistä:
SDL_FreeSurface(Osoite);
Olipas mukavaa illanviettoa :)
Lumi-ukkeli kirjoitti:
Lähdekoodit pitäisi kääntyä Linuxille ilman ongelmia.
Missä Makefile? Aika turhauttavaa alkaa manuaalisesti kääntämään monen tiedoston projektia.
Gaxx kirjoitti:
Edit2: Haaa! Tiesin, että vika on dekonstruktoreissa! :)
Edellä mainitsemani virheet on hyvä korjata, mutta itse sulkemisessa tapahtuva virhe aiheutuu Pinta.h tiedossa sijaitsevasta Pinta-luokan destruktorin ainokaisesta rivistä:SDL_FreeSurface(Osoite);Olipas mukavaa illanviettoa :)
Kiitos! Yritetään korjata löytämäsi virheet, mutta sanos että mikä tuossa Pinta-luokan tuhoajassa on sitten pielessä? Omasta mielestäni siinä ei ole mitään. En osaisi ainakaan korjata.
X ja Y koordinaatit eivät ole sekaisin, koska jos katsot sitä map-tiedostoa niin olen sen järjestänyt niin että sen muokkaaminen käsin on helppoa.
Blaze kirjoitti:
Missä Makefile? Aika turhauttavaa alkaa manuaalisesti kääntämään monen tiedoston projektia.
g++ -o asdf *.cpp
Pari vaadittavaa kirjastoa vain perään virheilmoitusten perusteella. Ei tuo minusta nyt kovin turhauttavaa ole.
Lumi-ukkeli kirjoitti:
X ja Y koordinaatit eivät ole sekaisin, koska jos katsot sitä map-tiedostoa niin olen sen järjestänyt niin että sen muokkaaminen käsin on helppoa.
Lähinnä tarkoitin sitä, että varaat muistia
tilemap[MapWidth][MapHeight]:lle
ja kuitenkin käytät taulukkoa
tilemap[MapHeight][MapWidth]:na.
Eli, jos kentän leveys ja korkeus eivät ole samat, syntyy muistivuoto.
Joo löytyhän sieltä pieni virhe, mutta sen korjaaminen ei auttanut ollenkaan. Peli kaatuu vieläkin, tosin paikallistin virheen: Peli kaatuu kun tilemap-taulukko deletoidaan.
Ohessa nykyinen koodi. Tämä on jo niin lyhyt että suurin osa porukasta jaksaa jo paneutua tuohon koodiin:
unsigned short **tilemap; // tilemapin varaus, ja täyttö. MapWidth ja MapHeight muuttujissa on dynaamisen kaksiulotteisen taulukon koko. tilemap = new unsigned short*[MapWidth]; for(int i = 0; i < MapWidth; i++) { tilemap[i] = new unsigned short[MapHeight]; } for(int y = 0; y < MapHeight; y++) { for(int x = 0; x < MapWidth; x++) { myfile >> tilemap[x][y]; } } //deletointi: for(int i = 0; i <= MapWidth; i++) { delete [] tilemap[i]; } delete [] tilemap;
Eli tuosta koodinpätkästä heittää virheen "Access violation -Segmentation Fault"
Lumi-ukkeli kirjoitti:
//deletointi: for(int i = 0; i <= MapWidth; i++) { delete [] tilemap[i]; } delete [] tilemap;
Eikös tuossa pitäisi olla
for(int i = 0; i < MapWidth; i++)
Muistivirheitä ei tule aina pelkästään muistin varaamisen ja vapauttamisen kanssa. Samannäköisiä virheilmoituksia tulee, jos osoittelee väärin noita varattuja ja vapautettuja muistialueita.
Muuten, minusta tällaisten touhujen hoitamiseen kannattaisi käyttää C++:aa. :-)
viimeisessä for:issa on "="-merkki liikaa. No niin just... :]
joo oli liikaa mutta ei sekään auttanut :(
http://www.geocities.com/spur4444/prog/
Tein kaiken niinku tuossa mutta siltiki meinaa et toi kusee.
Lumi-ukkeli kirjoitti:
Peli kaatuu vieläkin, tosin paikallistin virheen: Peli kaatuu kun tilemap-taulukko deletoidaan.
En tiedä, oletko tehnyt koodiisi kovinkin radikaaleja muutoksia, mutta jos kommentoin tilemapin vapauttamisen pois julkaisemastasi ohjelmasta, se ei vaikuta mitenkään siihen, kaatuuko ohjelma vai ei. Ainoastaan Pinta luokan destruktorin pois kommentoinnin olen havainnut estävän kaatumisen.
Yksi mahdollinen syy kaatuiluun on se, että käytät FreeSurface():a osoittimeen, joka osoittelee väärään paikkaan muistia ja se ei ole NULL. En tosin löytänyt tuollaista tapausta, vaikka sitä jonkin aikaa etsin, mutta en jaksanut käydä kaikkia mahdollisia tapauksia läpi.
Vika on tosiaankin tuossa mapin lataamisessa ja tuhoamisessa.
mutta kommentoippa pois koodi mikä on tuolla mureakuhan pastessa riveillä 435-454 ja kokeile sitten kaatuuko :D
Lumi-ukkeli kirjoitti:
Vika on tosiaankin tuossa mapin lataamisessa ja tuhoamisessa.
Olisi kiva tietää millä perusteella. Jos debuggeri sanoo jotain, se on usein vain suuntaa antava ohje ja loppu pitää päätellä itse.
Lumi-ukkeli kirjoitti:
mutta kommentoippa pois koodi mikä on tuolla mureakuhan pastessa riveillä 435-454 ja kokeile sitten kaatuuko :D
Mitä järkeä tuossa nyt on? Se nyt on kokeilemattakin selvää, että kaatuu, kun yritetään käsitellä varaamatonta muistia.
PS. Kääntäjäni on MinGW(Dev-cpp)
Gaxx se ei mulla kaatunu ku kommentoin pois...
http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fQuit:
Plus, using atexit in a library is a sure way to crash dynamically loaded code.
SDL ei tiettävästi käytä atexit-funktiota, ja muutenkin, kaatumiset yleensä ovat omassa koodissa. Tiedän, niitä on ikävä etsiä, mutta sille ei voi mitään. Tuo on kuitenkin jo sen kokoinen projekti, että välttämättä ihan ketä tahansa ei kiinnosta lukea sitä läpi yhden tai parin virheen perässä. Debuggerin käytön opettelu on harvinaisen loistava idea.
Aihe on jo aika vanha, joten et voi enää vastata siihen.