Qt: Klasse als Member und nicht als Pointer deklariert -> crash



  • Namenloser342 schrieb:

    Wie soll das konkret mit der Deklaration von std::pair als pointer bzw. als nicht pointer erklärt werden. Interessiert mich.

    Du änderst damit die Größe des Members, und damit das Speicherlayout der enthaltenden Klasse. Damit kann es sein, dass du dir in der einen Variante eine wichtige Stelle im Speicher zerschießt (Absturz), und mit der anderen eine nicht so wichtige (kein Fehler, oder falsche Werte, die du bisher nicht entdeckt hast, oder es knallt irgendwann später).

    Allgemein ist es nicht sinnvoll, sich zu fragen, warum sich Code so oder so verhält, wenn undefiniertes Verhalten im Spiel ist. Es kann alles mögliche passieren. Es kann auch sein, dass derselbe Code mal läuft und mal nicht.



  • arghonaut schrieb:

    Bitte mach doch auch mal selber was. Entweder google->Heap zerschossen, oder wirklich mal per Debugger reingehen.

    liest du überhaupt was ich hier schreibe?



  • Namenloser324 schrieb:

    liest du überhaupt was ich hier schreibe?

    Sicher, aber du ignorierst seit meinem ersten Post, was ich (und andere) schreibe.
    * Es liegt NICHT daran, was du in dieser Klasse machst
    * Es liegt NICHT an std::pair oder std::pair*
    * Es ist undefiniertes Verhalten
    * Du sollst einen Debugger verwenden.
    * Wenn du nicht selber zurande kommst, sollst du ein komplettes, kompilierbares Programm liefern, das deinen Fehler aufweist.

    Da du irgendwie undefiniertes Verhalten produzierst kann man auch nicht erklären, warum es mit dem Pointer klappt aber nicht ohne. Der Fehler liegt einfach an einer ganz anderen Stelle (was hier jetzt auch schon genügend oft erklärt wurde).
    Wenn du dich weiter so dagegen sträubst, wird man dir auch nicht helfen können - sorry.



  • Hallo, da dieser Fehler jetzt später bei einem gleichen Fall auftritt, poste ich hier mal den code als zip datei + verwendeter bilder und dann könnt ihr mir vielleicht helfen, denn das debuggen bringt nichts, da das programm funktioniert, sobald ich den debugger verwende.
    Es geht um die Variable "QBitmap imagemask;", zu finden in Groundeditor.h im privaten Klassenbereich. Als Pointer funktioniert der Code.

    hier das projekt:
    http://www.mediafire.com/?bbz66y77wmyoayd

    der code muss an zwei stellen geändert werden:
    ihr müsst die Bildadresse zu den neuen Adressen auf euren Festplatten ändern:

    In Groundeditor.cpp im ersten Konstruktor muss die Adresse der Terraindatei geändert werden.
    In mywidget.cpp weit oben, muss das define geändert werden zur adresse der test.png auf eurer festplatte.
    Dann sollte es starten.

    Wie gesagt, wenn ich den Debugger laufen lasse, funktioniert (wenn auch schleppend) das Programm ohne Absturz. Wenn ich es normal ausführe stürzt es sofort ab.



  • Das der Code schlecht strukturiert ist, ist mir schon klar. Darum soll es hier nicht gehen.



  • Eine Anleitung, um den Crash zu produzieren, wäre nicht shclecht gewesen. Ich hab es gestartet -> alles OK, ein wenig rumgeclickt -> alles OK.

    Aber dein Code... da wundert mich nichts 😃
    Prinzipiell erachte ich alle Zugriffe auf CannonField::target_parcel als problematisch. Wenn sich der Iterator ändert -> BUMM! Deine Zugriffe in cannonfield.cpp, Z.111 und Z.116 sind EXTREM fehleranfällig und verdächtig (ungeprüfte Inkrementierung des Iterators + Zuweisung).

    Du hängst jetzt schon Tage an dem Problem. In der Zeit hättest du dir auch prima Gedanken über ein besseres Design machen können. Mein Tip: Verwirf den bisherigen Code und fang nochmal neu an.



  • Hast du immernoch nichts gelesen? Ich sagte ZIGFACH das ich schon lange das ganze mit Pointern umgangen habe. Ich hänge da gar nicht, aber schön das du mir meine Vorbehalte bestätigst.

    edit: aber sehr gut, dass es bei dir funktioniert, bei mir nicht. Also ein Bug?



  • kingcools schrieb:

    Hast du immernoch nichts gelesen? Ich sagte ZIGFACH das ich schon lange das ganze mit Pointern umgangen habe. Ich hänge da gar nicht, aber schön das du mir meine Vorbehalte bestätigst.

    * Halt dich zurück... *
    Ich mach mir nach all dem Trara echt die Mühe und schau in den Code, den du gnädigerweise hochgeladen hast. Er kompilierte nicht auf Anhieb, gut, egal. Dann beheb ich das. 5 Minuten futsch. Dann stocher ich *in deinem Code, den du uns zum Anschauen gegeben hast* (!!!) rum (15 Minuten?). Dann fallen mir die ganzen Iteratoren auf. Ich sag dir das *höflich* (leicht ironisch, aber das muss man aushalten).

    UND DANN SO EINE REAKTION?

    Entweder willst du uns verarschen, oder du weißt nicht was du sagst, oder du hast den falschen Code gepostet. Auf jeden Fall legt der gepostete Code nahe, dass deine Erfahrung nicht die größte ist, und dann sollte man sich GENAU überlegen, in welchem Ton man antwortet.

    Für mich wars das in dem Thread. Ich habe versucht zu helfen (auch wenn du das nicht erkennen willst). Vielleicht hat ja sonst noch jemand Zeit, sich für seine kostenlos inverstierte Zeit anpflaumen zu lassen.

    PUNKT!



  • Es ist zwar nett, dass du in den Code geschaut hast, dafür danke.

    Wer nicht liest was ich hier schreibe, braucht sich nicht zu wundern, wenn ich nach der MINDESTENS 3ten Wiederholung davon, genervt bin.
    Zumal du auch noch darauf rumreitest, dass ich ja in der Zeit die ich vermeintlich warten musste, ja mir gleich ein neues Design erdenken hätte können.

    Erst kommst du in den Thread, behauptest das könne ja nicht so sein, ignorierst dass es nun mal doch so sei, glaubst mir nicht, siehst den Code und glaubst mir dann scheinbar wieder nicht. Dann tust du auch noch so, als sei meine Reaktion jetzt so übertrieben und unpassend.

    Wenn du nichtmal lesenverständnis besitzt, glaube ich nicht, dass du mir helfen kannst.
    Auf Wiedersehen.



  • kingcools schrieb:

    Es geht um die Variable "QBitmap imagemask;", zu finden in Groundeditor.h im privaten Klassenbereich. Als Pointer funktioniert der Code.

    Kapier es bitte endlich: Es liegt nicht an dieser oder jener Variable, die gerade zufällig das undefinierte Verhalten so beeinflusst, dass es knallt.

    Stell dir mal vor, jemand fährt immer über eine Kreuzung, ohne auf die Ampel zu achten. Da er das immer nachts um 2 macht, geht das auch immer gut. Nun versucht er es morgens um 8 und prompt kommt es zu einem Unfall. Schlussfolgerung: Die Uhrzeit ist die Ursache des Problems. Denn wenn er es nachts um 2 macht, funktioniert es ja.

    Genauso ist es bei dir. Du machst in deinem Code etwas grundsätzlich falsch, und das kann (muss aber nicht) dazu führen, dass dein Programm in bestimmten Situationen abstürzt.

    Du musst deinen gesamten Code prüfen. Bau überall dort, wo du einen Array-Index berechnest, eine Prüfung ein, ob der Index im gültigen Bereich liegt. Prüf überall dort, wo du einen Iterator benutzt, ob er gültig ist. Prüf überall dort, wo du einen Iterator modifiziert, ob er danach auch noch in den gültigen Bereich der Sequenz verweist.

    Dadurch kommst du dem Problem auf die Spur, nicht durch das Herumdrehen an der einen Stelle, die gerade das Verhalten beeinflusst.



  • Danke für deinen Hinweis, damit ich es auch richtig verstehe, nochmal mein Gedankengang dazu:

    Der Code in dem der Fehler auftrat existiert nicht mehr, daher ist das jetzt nur noch Spekulation:

    Der Code funktionierte JEDESMAL(!) ohne Fehler wenn ich entweder besagte Variable auskommentierte oder sie als Pointer deklarierte. Tat ich das nicht gab es IMMER einen Fehler beim Start.
    Absolut ohne Ausnahme.
    Das legt in meinem Verständnis den Schluss nahe, dass das Problem direkt mit eben dieser Variable zu tun hat.
    Wäre es eine Iteratorkalkulation die nicht korrekt ausgeführt wird oder irgendein Arrayindize der außerhalb des gültigen Bereiches läuft, so müsste dies auch bei Deklaration der besagten Variable als "nicht pointer" auftreten, denn die Berechnungen sind deterministisch(damit meine ich explizit NICHT die Folgen der Berechnung, welche ja bei fehlerhaftem Code undefiniertes Verhalten hervorrufen können).
    Das heißt für mich jedoch, dass mindestens zu irgendeinem Zeitpunkt Fehler irgendeiner Art(falsche Anzeige, Absturz o.ä.) auftreten müssten. Dies habe ich jedoch absolut nicht bemerken können.

    Als ich dann versucht habe, mittels Debugger den Fehler zu finden, funktionierte das Programm plötzlich auch mit "Pointervariable".

    Um mal bei deinem Beispiel zu bleiben:
    Ich fahre sehr häufig pro Tag über besagte Ampel ohne einen Unfall zu haben, dann plötzlich lackiere ich mein Auto um und absolut jedes Mal wenn ich über die Ampel fahre baue ich einen Unfall.
    Nun lackiere ich das Auto wieder um und fahre immer wieder über die Ampel und baue keinen Unfall mehr.
    In meinem Verständnis wäre dann anzunhemen, wenn alle anderen Randbedingungen konstant bleiben, dass irgendie die Lackierung die Unfälle verursacht.



  • kingcools schrieb:

    Der Code funktionierte JEDESMAL(!) ohne Fehler wenn ich entweder besagte Variable auskommentierte oder sie als Pointer deklarierte.

    std::pair<int,int> test;
    

    Ist ein völlig korrekter und Fehlerfreier Code. Dieser Code führt NIEMALS zu einem Fehler! Wenn überhaupt führt das dadurch geänderte Speicherlayout zu einem Fehler, falls du IRGENDWO anders einen Fehler gemacht hast.

    Solche Fehler kenne ich selbst aus mehreren Projekten, wo irgendwer bescheidenen Code geschrieben hat, aber weil es jetzt an einer anderen Stelle knallt, Diese dafür Verantwortlich sein soll.

    Glaub es einfach; Und wenn du mir nicht glauben willst: ich bin seit mehr als 10 Jahren beruflich mit der C++ Programmierung beschäftigt - Solche Fehler können vorkommen, haben aber NICHTS, ich wiederhole NICHTS mit dem korrekt deklarierten std::pair zu tun.



  • Ok, danke 🙂



  • kingcools schrieb:

    Ok, danke 🙂

    😮
    asc hat doch jetzt nichts erzählt, was wir hier nicht schon Seitenweise zu erklären versuchen. Haben dich die 10 Jahre berufliche C++-Erfahrung zum Umdenken bewegt?

    Um mal bei deinem Beispiel zu bleiben:
    Ich fahre sehr häufig pro Tag über besagte Ampel ohne einen Unfall zu haben, dann plötzlich lackiere ich mein Auto um und absolut jedes Mal wenn ich über die Ampel fahre baue ich einen Unfall.
    Nun lackiere ich das Auto wieder um und fahre immer wieder über die Ampel und baue keinen Unfall mehr.
    In meinem Verständnis wäre dann anzunhemen, wenn alle anderen Randbedingungen konstant bleiben, dass irgendie die Lackierung die Unfälle verursacht.

    Dein Verständnis trügt. Denn nicht die andere Lackierung verursacht den Unfall.
    Ein Bauer war früher Besitzer des Landes. Er hat hier immer seine Stiere weiden lassen. Dass ihm das Land nicht mehr gehört hat er nicht geprüft, (und damit nicht mitbekommen, dass da mittlerweile kein Gras mehr ist, sondern eine Kreuzung). Den Unfall gibt es jetzt auch nur DESHALB, weil die neue Farbe rot ist, und die Stiere (die jetzt plötzlich auf der Straße stehen) von Rot angezogen werden. Dein grünes Auto ist denen gar nicht aufgefallen.


Anmelden zum Antworten