Anzeige:
Ergebnis 1 bis 3 von 3

Thema: Kleiner Segfault mit QStrings

  1. #1
    Registrierter Benutzer
    Registriert seit
    08.07.2002
    Beiträge
    719

    Kleiner Segfault mit QStrings

    Hi,
    ich wollte in einem größeren Programm das Erstellen von mehreren gleichartigen Widgets durch eine Widgetfactory lösen, leider kommt es dabei zu einem Speicherzugriffsfehler, den ich mir nicht erklären kann: (Ist eine kleine Beispielapp, der Fehler dürfte aber der gleiche sein)
    Code:
    #include <qwidget.h>
    #include <qstringlist.h>
    #include <qvbox.h>
    #include <qpushbutton.h>
    #include <qapplication.h>
    
    class Factory
    {
     public:
      QStringList keys() const { return QStringList() << "QPushButton"; }
      QWidget* create(const QString & key, QWidget* parent = 0, const char* name = 0)
      {
       if(key == "QPushButton")
         return new QPushButton("PushButton",parent, name);
       return 0;
     }
    };
    
    
    class MainWindow : public QVBox
    {
     public:
      MainWindow();
    };
    
    MainWindow::MainWindow() : QVBox(0)
    {
     Factory* factory = new Factory();
    
     for(QStringList::Iterator it = factory->keys().begin(); it != factory->keys().end(); ++it)
      factory->create(*it, this);
    
     delete factory;
    }
    
    int main(int argc, char** argv)
    {
     QApplication app(argc, argv);
     MainWindow mw;
     app.setMainWidget(&mw);
     mw.show();
     return app.exec();
    }
    Dabei kommt es zu folgenden merkwürdigen Fehlern:

    Starting program: /home/axel/Documents/factory
    [New Thread 16384 (LWP 2653)]

    Code:
    Program received signal SIGSEGV, Segmentation fault.
    [Switching to Thread 16384 (LWP 2653)]
    0x4050c95e in operator==(QString const&, char const*) ()
       from /usr/lib/qt3/lib/libqt-mt.so.3
    Current language:  auto; currently c
    (gdb) bt
    #0  0x4050c95e in operator==(QString const&, char const*) ()
       from /usr/lib/qt3/lib/libqt-mt.so.3
    #1  0x40012780 in environ () from /lib/ld-linux.so.2
    #2  0x0804b802 in MainWindow (this=0xbffff510) at factory.cpp:31
    #3  0x0804b889 in main (argc=1, argv=0xbffff654) at factory.cpp:39
    #4  0x407827f7 in __libc_start_main () from /lib/i686/libc.so.6
    (gdb)
    In meinem großen Programm hab ich noch lustigere Sachen entdeckt, unter anderem Segfaults in QMotifStyle, was ich noch nie angefasst habe

  2. #2
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477

    Re: Kleiner Segfault mit QStrings

    Dein Problem liegt hier:

    Code:
     for(QStringList::Iterator it = factory->keys().begin(); it != factory->keys().end(); ++it)
      factory->create(*it, this);
    factory->keys() gibt jedes mal eine neue Kopie einer StringList zurück.
    Das temporäre return Objekt gilt nur bis zum Ende des Statements, hier also zB nur bei der Iteratorinitialisierung, aber nicht merh im Schleifenbody.

    Außerdem sind die Iteratoren sind nur in einer Instanz eines Containers stabil.

    Zwei Lösungsmöglichkeiten:

    Code:
    private:
      QStringList keylist;
    public:
      Factory() { keylist << "QPushButton"; }
      const QStringList& keys() const { return keylist; }
    
    // ...
    
     for(QStringList::ConstIterator it = factory->keys().begin(); it != factory->keys().end(); ++it)
      factory->create(*it, this);
    Also mit const Reference und festem Listen Objekt oder einfacher mit lokalem Zwischenobjekt:
    Code:
     QStringList keys = factory->keys();
     for(QStringList::Iterator it = keys.begin(); it != keys.end(); ++it)
      factory->create(*it, this);
    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  3. #3
    Registrierter Benutzer
    Registriert seit
    08.07.2002
    Beiträge
    719
    Hm, hab ich jetzt auch gemerkt. In der Doku von Trolltech steht auch: "You should make a copy". Ich hab die zweite Lösung gemacht und es funktioniert.

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •