QImage Memory Leak



  • Hallo,
    ich habe ein Problem mit QImage ich will eine eigenen Speicherbereich per QImage anzeigen lassen und habe das Problem daß das Programm abstürzt oder einen falschen Speicherbereich anzeigt, solange ich das mache wie hier habe ich kein Problem. Wenn ich allerdings ausserhalb den Speicher per new reserviere und auch das QImage ausserhalb anlege dann stürzt das Programm ab bzw. sehe ich bei Größenänderung des Fensters wie sich der Speicher verändert. Hat das irgendwas mit dem Eventhandler zu tun.

    void Widget::paintEvent(QPaintEvent *event)
    {
        // Wenn ich das hier im Ctor mache dann kommt Mist raus
        unsigned char* data = new unsigned char[320*200*3];
        QImage img(data, 320, 200, QImage::Format_RGB888);
        // Wenn ich das hier im Ctor mache dann kommt Mist raus
    
        QPainter p(this);    
    
        p.begin(this);
        p.drawImage(0, 0, img);
        p.end();
    
        delete[] data;
    }
    

    Wer kennt sich damit aus und kann helfen?



  • Es ist immer gut, bei einem Problem den Code zu posten, der funktioniert...
    Was meinst du mit "sehe ich bei Größenänderung des Fensters wie sich der Speicher verändert"?
    Poste doch bitte den Problemcode, natürlich kompilierbar und auf den Fehler beschränkt, der natürlich sichtbar sein muss.

    Qt zaubert nicht, die müssen auch mit dem zurecht kommen was C++ bietet (moc/uic erzeugen auch nur C++-Code). Wenn Probleme auftreten dann meistens wegen Fehlern im eigenen Code.
    Und ein Memory Leak sorgt nicht gleich für Abstürze.



  • Mein angeforderter Speicher und der den QImage nutzte waren nicht identisch, der von QImage war sogar undefiniert und logisch das es da kracht.

    Dank des Debuggers von Qt-Creator konnte ich super nachvollziehen was passiert ist. Danke für die angebotene Hilfe.

    Gruß Blue-Tec



  • blue-tec schrieb:

    Mein angeforderter Speicher und der den QImage nutzte waren nicht identisch, der von QImage war sogar undefiniert und logisch das es da kracht.

    Kann ich mir nicht vorstellen:

    QImage::QImage ( uchar * data, int width, int height, Format format )
    Constructs an image with the given width, height and format, that uses an existing memory buffer, data. The width and height must be specified in pixels, data must be 32-bit aligned, and each scanline of data in the image must also be 32-bit aligned.

    The buffer must remain valid throughout the life of the QImage. The image does not delete the buffer at destruction.

    Letzteres ist in jedem Fall bei dir verletzt, da du data vor dem QImage zerstörst (in dem von dir geposteten Codeabschnitt).

    Dank des Debuggers von Qt-Creator konnte ich super nachvollziehen was passiert ist. Danke für die angebotene Hilfe.

    Verrätst du uns noch, was das Problem war und wie die Lösung aussieht? Hilft evtl. Leuten die vor dem selben unerklärlichen Verhalten stehen.



  • Hallo Labrador,

    auch wenn du es dir nicht vorstellen kannst, ist es so gewesen. Hier erkläre ich dir wieso:

    // die Headerdatei
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = 0);
        ~Widget();
    
    protected:
        void paintEvent(QPaintEvent *event);
    
    private:
        QPainter p;   
        VFramebuffer fb; // das hier war mit QImage img; vertauscht 
        QImage img;      // somit konnte fb noch keinen gültigen Speicher erzeugt haben
    };
    
    // Implementierung
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        p(this),
        fb(640, 480), // hier steht zwar die richtige Reihenfolgen aber die 
                      // Reihenfolge der Deklaration zählt ja
        img(fb.ptr_data(), 640, 480, QImage::Format_RGB888)
    
    {
        resize(640, 480);
    }
    
    void Widget::paintEvent(QPaintEvent *event)
    {
        p.begin(this);
        p.drawImage(0, 0, img);
        p.end();
    }
    

    Die Speicherstellen verglichen haben ich mit QImage::bits() vor der Änderung waren sie unterschiedlich danach waren sie gleich, somit war das der Grund des Fehlers der nun behoben ist.

    Gruß Blue-Tec



  • Das ist aber ein C++-Problem. Die Member werden - ungeachtet der Reihenfolge in der Initialisierungsliste - in der Reihenfolge ihrer Deklaration in der Klassendefinition initialisiert. Wenn Member bei der Initialisierung voneinander abhängen muss deren Deklarationsreihenfolge passen, sonst krachts.
    Meine Annahme fußte auf der Voraussetzung, dass data bereits korrekt initialisiert wurde. Deine Aussage hat diesen Fakt aber unterschlagen.



  • Ich habs blöd beschrieben das stimmt, sorry. Danke trotzdem für deine Mühe.

    Gruß Blue-Tec


Anmelden zum Antworten