Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++/Qt4.6: Mystinen segmentation fault

Sivun loppuun

TsaTsaTsaa [02.02.2010 17:43:49]

#

Ongelmallinen koodinpätkä:

// ...
qDebug() << "DEBUG 2";
  if ( rootItem_ ) { // <--- TÄSTÄ TULEE SEGFAULT!??!?!?
    qDebug() << "DEBUG 3";
    // ...

rootItem_ on osoitin omaan luokkaan FileBrowserTreeItem. Ohjelmaa ajettaessa tulostuu "DEBUG 2", jonka jälkeen "segmentation fault". En todellakaan tajua miten osoittimen tarkistuksesta voi tulla segmentation fault?

aaämdee [02.02.2010 17:56:21]

#

Arvaus:
Jos tuo rootItem_ on 0 (et ole laittanut osoitinta osoittamaan mihinkään), niin hypätään tuosta if-lauseesta yli ja joku seuraava rivi voi aiheuttaa segfaultin, eli segfaultin aiheuttamaa koodia ei viestissäsi näkyisi?

Metabolix [02.02.2010 18:17:58]

#

Tuo aaämdeen arvaus on aika hyvä. Kokeilepa vaihtaa ensimmäisen debug-tulosteen paikalle gDebug() << (rootItem_ ? "rootItem_ ok" : "rootItem_ == 0").

TsaTsaTsaa [02.02.2010 18:25:43]

#

Siis toki minulla on if-haaran jälkeenkin debug-tuloste eli olen rajannut ongelman tuohon.

E: Ja nyt kun kokeilin laittaa tuon Metabolixin ehdotelman, niin edes se ei tulostu. Eli jostain kumman syystä kaatuu heti kun rootItemiä yrittää tarkastella.

Metabolix [02.02.2010 18:30:26]

#

Oletko debuggerilla kokeillut? Sellainen varmaan osaisi kertoa heti, missä vika on. (Hae GDB quick start.)

os [02.02.2010 18:32:54]

#

Mahtaako tuo rootItem_ olla jäsenmuuttuja? Jos näin on, niin olet luultavasti tekemässä näin

oliop->metodi()

tai näin

oliov.metodi()

oliolle, jota ei ole (enään) olemassa tai pointteri osoittaa muuten minne sattuu.
Tällöin "segmentation fault" -virhe ilmenee tyypillisesti ensimmäisen viittauksen this->jasen kohdalla.

TsaTsaTsaa [02.02.2010 18:41:42]

#

@Metabolix: Debuggeri näytti Qt:n syövereihin asm-koodiin, ei paljon apuja.

@os: rootItem_ on jäsenmuuttuja, mutta en ole tekemässä noin, vaan kuten ensimmäisessä viestissäni lukee, ainoastaan tarkastamassa osoittaako osoitin mihinkään ja tarkastus jo aiheuttaa virheen, mikä on mielestäni hyvinkin mystistä. Voisiko vika olla uudehkossa Qt 4.6:ssa?

EDIT: Sen verran debuggerista kuitenkin selviää, että oliolla, jossa tuo koodinpätkä suoritetaan this-osoittimen arvo on 0x0. Melko kummalliselta haiskahtaa sekin?

os [02.02.2010 18:54:38]

#

Jos se on jäsenmuuttuja, niin olet (tai Qt on) varmasti tekemässä noin. Siirry siis debuggerissa/debuggauksessa yksi taso ylöspäin ja katso, että kutsut metodia (siis sitä metodia, jonka sisällä tuo postaamasi koodi on) validille oliolle. Jos tämä kutsu tulee Qt:n syövereistä, niin olet luultavasti antanut sille jossakin vaiheessa viittauksen, joka ei tällä hetkellä jostain syystä osoita validiin olioon.

Metabolix [02.02.2010 18:59:23]

#

// Funktion alkuun:
if (!this) {
  qDebug() << "!this, paha juttu!"; // GDB:llä breakpointti tähän.
}

Edit: Qt:stäkin varmaan on saatavilla debuggerille paremmin soveltuva versio, tai ainahan sen voi kääntää itse.

TsaTsaTsaa [02.02.2010 18:59:41]

#

No niin no noinhan se olikin eli olemattomaan olioon sörkittiin. 0x0-thissistähän se tosiaan viimeistään olisi pitänyt hoksatakin. Kiitoksia vaan!

EDIT: Mutta miksi ohjelma kaatuu vasta olemattoman olion metodin sisällä eikä jo olemattoman olion metodikutsun yhteydessä? Melko hämäävää.

os [02.02.2010 19:08:56]

#

Tämä johtuu siitä, millaiseksi konekieliseksi ohjelmaksi C++ käytännössä kääntyy ja miten käyttöjärjestelmä suorittaa kyseisen ohjelman. Metodikutsu vastaa konekielisessä koodissa täysin validia funktiokutsua riippumatta siitä, mihin this-pointteri osoittaa. This-pointterin referointi (kohdassa this->rootItem_) taas tässä tapauksessa (this==0x0) aiheuttaa muistiviittauksen kiellettyyn paikkaan, jolloin käyttöjärjestelmä viheltää pelin poikki.

TsaTsaTsaa [02.02.2010 19:17:06]

#

Aivan.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta