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



  • Du wirst doch irgendwo auf "test" zugreifen, also was reinschreiben. Denn nur bei der Deklaration kann es keinen crash geben.

    Übrigens kannst du anstatt STL auch das Qt-Äquivalent QPair nehmen.



  • Softwaremaker schrieb:

    Du wirst doch irgendwo auf "test" zugreifen, also was reinschreiben. Denn nur bei der Deklaration kann es keinen crash geben.
    .

    Was nicht sein darf, kann nicht sein? Er sagt ja, das er es nur anlegt und nicht zugreift.

    Softwaremaker schrieb:

    Übrigens kannst du anstatt STL auch das Qt-Äquivalent QPair nehmen.

    OK, aber die Frage ist damit immer noch nicht beantwortet? Kann ja nicht die Lösung sein.

    Artchi

    PS: Ich nutze kein Qt, bin nur Zuschauer.



  • Softwaremaker schrieb:

    Du wirst doch irgendwo auf "test" zugreifen, also was reinschreiben. Denn nur bei der Deklaration kann es keinen crash geben.

    Übrigens kannst du anstatt STL auch das Qt-Äquivalent QPair nehmen.

    Also ich habe die Variable sogar umbenannt um zu schauen ob ich vielleicht irgendwo die benutzung davon vergessen hatte-> nichts.
    Ich habe zuerst auch std::pair benutzt und danach QPair versucht, beides verursachte Fehler. Ebenso std::map, welches ich testete um zu schauen wie es mit anderen Containern aussieht.
    std::vector funktioniert als "nicht pointer" z.B.



  • Und jetzt starte bitte endlich dein Programm im Debugger. Es liegt nämlich sicher nicht an dem Member(-Typ). Das ist klassisches undefiniertes Verhalten, du hast sogar Glück dass es zum Crash kommt... Wahrscheinlich zerschießt du dir irgendwo den Heap, castest wild durch die Gegend oder treibst andere Späße.

    Wenn du trotzdem nicht weiterkommst, ist auf jeden Fall ein vollständiges, kompilierbares Beispielprogramm notwendig, das deinen Fehler erzeugt.



  • Poste mal deinen kompletten Code, wenns nicht zu viel ist. Auch wo du auf "someclass" zugreifst.



  • Ich habe dann mit den Pointern weitergearbeitet, weil ich gerade heiß aufs programmieren war, ich versuche aber die klasse zu rekonstruieren:

    #include <QWidget>
    #include <QPicture>
    #include <QPoint>
    #include <QToolBar>
    #include <QPair>
    
    #define BUTTON_PER_ROW 10
    #define TILE_PER_LINE 16
    #define TILE_SIDE 32
    #define TILE_SIDEF 32.0f
    
    class GroundEditor:public QWidget
    {
    Q_OBJECT
    public:
        GroundEditor(QWidget* parent);
        ~GroundEditor();
        void releasePainter(void);
    
    protected:
        void paintEvent(QPaintEvent *);
    
    signals:
        void sendCursorData(QPair<int,int>*,QPixmap*);
        void sendTileset(QPixmap*);
    private:
    
    QPixmap* image;
    QPair<int,int> begin_end;
    
        void setupWindow(void);
        void leaveEvent ( QEvent * event );
        bool allow_paint;
    
    };
    
    #endif // TYPEEDITOR_H
    

    Das war so ziemlich die Definition und hier die c++ datei(so ca.):

    #include <QGridLayout>
    #include <QSizePolicy>
    #include <QAction>
    #include <QPainter>
    #include <QMouseEvent>
    #include "Groundeditor.h"
    
    typedef unsigned short US;
    GroundEditor::GroundEditor(QWidget* parent)
        :QWidget(parent),allow_paint(false)
    {
    
        image = new QPixmap("C:\\QtSDK\\Projekte\\Test\\Grafikmaterial\\terrain.png","PNG");
       // sendTileset(image);
    
        this->setupWindow();
    
    }
    
    GroundEditor::~GroundEditor()
    {
    }
    
    void GroundEditor::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        if(allow_paint)
        {
    
        painter.drawPixmap(0,0,*image);
        for(unsigned int w = 1; w <= TILE_PER_LINE;w++)
            painter.drawLine(TILE_SIDE*w,0,TILE_SIDE*w,image->height());
        for(unsigned int h = 1;h <= TILE_PER_LINE;h++)
            painter.drawLine(0,h*TILE_SIDE,image->width(),h*TILE_SIDE);
    
        }
    
    }
    
    void GroundEditor::setupWindow(void)
    {
    Qt::WindowFlags myflag = 0;
    myflag = Qt::Widget;
    myflag |= Qt::CustomizeWindowHint;
    QWidget::setWindowFlags(myflag);
    this->setGeometry(0,0,image->width(),image->height());
    this->setFixedSize(image->width(),image->height());
    setFocusPolicy(Qt::StrongFocus);
    
    }
    
    void GroundEditor::leaveEvent ( QEvent * event )
    {
        emit sendCursorData(begin_end,image);
    }
    
    void GroundEditor::releasePainter(void)
    {
        allow_paint = true;
        update();
    }
    

    So ungefähr sah die aus.



  • Wie gesagt, ich hatte die Variable überhaupt nichtbenutzt, daher kann das mit dem casten nicht die Antwort gewesen sein.
    Ich habe dann das einfach akzeptiert und mit Zeigern weiterprogrammiert, läuft ohne Probleme.



  • ist zwar egal, da beide Varianten nicht funktioniet haben, aber die Variable "begin_end" war ein zweielementiger array. Habe das hier falsch editiert.



  • Namenloser342 schrieb:

    Wie gesagt, ich hatte die Variable überhaupt nichtbenutzt, daher kann das mit dem casten nicht die Antwort gewesen sein.

    Diese Vermutung hat mit der Variable überhaupt nichts zu tun. So ein Verhalten tritt auf, wenn Du irgendwo anders Murks gemacht hast. Nicht mit "der Variable Murks gemacht", sondern "Murks gemacht". Wenn Du Dir den Heap zerschießt, ist dem System herzlich egal welche Variable dort mal lag oder liegen sollte.



  • Zeile 25 in der h-Datei und Zeile 67 in der cpp-Datei passen nicht zusammen.
    Der erste Parameter beim Signal ist ein Zeiger aber du übergibst keinen Zeiger bei emit sendCursorData(begin_end, image).



  • Jojo, und wie gesagt ist das nicht die tatsächliche Datei sondern so ungefähr wie sie aussah.
    "Diese Vermutung hat mit der Variable überhaupt nichts zu tun. So ein Verhalten tritt auf, wenn Du irgendwo anders Murks gemacht hast. Nicht mit "der Variable Murks gemacht", sondern "Murks gemacht". Wenn Du Dir den Heap zerschießt, ist dem System herzlich egal welche Variable dort mal lag oder liegen sollte."

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



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



  • 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!


Anmelden zum Antworten