kostenloser Webspace werbefrei: lima-city


QT übergabe eines Objektarrays an einen slot?

lima-cityForumProgrammiersprachenC/C++ und D

  1. Autor dieses Themas

    omegano

    omegano hat kostenlosen Webspace.

    Sinn des Programms, ich möchte das mein Programm ein Objekt-Array durchsucht und die Ergebnisse in nen Textfeld postet soweit kein Problem. Aber...

    Ich hab das Problem das ich in unten genannten Code einen Segmentation Fault kriege. Ich denke mal es liegt daran das ich dem slot search() nicht das array mit übergeben habe. Ich hab auch mein Qt Buch schonmal durchgewälzt und keine Ahnung wie ich das machen soll. Ich werde wohl irgendwie einen SIGNAL schreiben müssen das den selben Parameter wie SLOT hat das habe ich schon herausgefunden. Aber wie könnte sowas hier Sinnvoll aussehen? Und was ich mich auch frage durch die Methode getDatabase(Data* myd[]) initialisiere ich ja das array myd[] mit den objekten, das funktioniert soweit auch alles ganz gut. Aber wieso muss ich überhaupt dem search slot das Objekt Array übergeben. Es ist doch ein Attribut dieser Klasse somit müsste das doch wenn es im Konstruktor initialsiert wurde, verfügbar und mit den Daten gefüllt sein.

    Header Datei

    #ifndef MAINFORM_H
    #define MAINFORM_H
    
    #include <QtGui>
    #include <QString>
    #include <QFile>
    #include "data.h"
    #include "ui_mainwindow.h"
    #define LENGTH 100000
    
    class MForm : public QMainWindow, private Ui::MainWindow {
        Q_OBJECT
    public:
        Data* myd[];
        MForm();
        ~MForm(){}
    protected slots:
        void search();
        void save();
    
    private:
        void getDatabase(Data* myd[]);
    };
    
    #endif // MAINFORM_H


    Quellcode-Datei:

    Ich hab den Code um die Sachen gekürzt die Funktionieren

    #include "mainForm.h"
    #include "db.h"
    
    MForm::MForm(){
        //Gui Initialisieren
        setupUi(this);
    
        //Daten
        Data* myd[LENGTH];
        for(int n=0; n<LENGTH; n++){
            myd[n] = NULL;
        }
        getDatabase(myd);
    
    
        //connects
        connect( pushButton , SIGNAL(clicked()),
                 this , SLOT(search()) );
        connect( lineEdit, SIGNAL(returnPressed()),
                 this , SLOT(search()) );
        connect( pushButton_2 , SIGNAL(clicked()),
                 this , SLOT(save()) );
    }
    
    void MForm::search(){
        QString str = lineEdit->text();
        QString buf,temp;
        str=str.toLower();
        textEdit->clear();
        for(int i=0 ; i<LENGTH ; i++){
            if( (myd[i]->owner.toLower()).indexOf(str)!= -1 ){
                buf.clear();
                buf+=buf.setNum(myd[i]->gala)+":";
                buf+=buf.setNum(myd[i]->system)+":";
                buf+=buf.setNum(myd[i]->plani)+" / ";
                buf+="von "+myd[i]->owner+"("+ myd[i]->points +" / "+myd[i]->az+")";
                buf+=" Planetenname: "+myd[i]->name;
                buf+=" Allianz: "+myd[i]->alli+"\n";
                temp=textEdit->toPlainText();
                temp.append(buf);
                textEdit->setPlainText(temp);
            }
        }
    }
    
    }
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Hallo omegano,

    ich habe eine Vermutung, wo die die Segmentation Fault auslöst.
    In Deinem Konstruktor deklarierst Du die lokale Variable myd und initialisierst diese. Aber die lokale Variable überdeckt natürlich das Objekt-Feld, welches daher weiterhin uninitialisiert ist.
    Also solltest Du als erstes folgendes machen:
    MForm::MForm(){
        //Gui Initialisieren
        setupUi(this);
    
        //Daten
        myd = new Data*[LENGTH];
        for(int n=0; n<LENGTH; n++){
            myd[n] = NULL;
        }
        getDatabase(myd);
    
    
        //connects
        connect( pushButton , SIGNAL(clicked()),
                 this , SLOT(search()) );
        connect( lineEdit, SIGNAL(returnPressed()),
                 this , SLOT(search()) );
        connect( pushButton_2 , SIGNAL(clicked()),
                 this , SLOT(save()) );
    }
    Im Destruktor musst Du das Array mit
    delete[] myd;
    wieder freigeben.
    Als zweites prüfst Du im Slot search() nicht ob myd[ i ] == NULL ist, was die nächste Fehlerquelle ist. Also probiere mal folgendes:
    void MForm::search(){
        QString str = lineEdit->text();
        QString buf,temp;
        str=str.toLower();
        textEdit->clear();
        for(int i=0 ; i<LENGTH ; i++){
            if(myd[i] != NULL && (myd[i]->owner.toLower()).indexOf(str)!= -1 ){
                buf.clear();
                buf+=buf.setNum(myd[i]->gala)+":";
                buf+=buf.setNum(myd[i]->system)+":";
                buf+=buf.setNum(myd[i]->plani)+" / ";
                buf+="von "+myd[i]->owner+"("+ myd[i]->points +" / "+myd[i]->az+")";
                buf+=" Planetenname: "+myd[i]->name;
                buf+=" Allianz: "+myd[i]->alli+"\n";
                temp=textEdit->toPlainText();
                temp.append(buf);
                textEdit->setPlainText(temp);
            }
        }
    }
    Ich denke, damit sollte es dann gehen.


    Beitrag zuletzt geändert: 18.5.2012 20:17:00 von darkpandemic
  4. Autor dieses Themas

    omegano

    omegano hat kostenlosen Webspace.

    also ich hab die erste änderung der deklaration funktioniert so nicht, die abfrage ob myd!=NULL abfrage hab ich mit eingebaut bewirkt aber nix, segfault immer noch da.

    ich hab ja Data* myd[] als attribut der class MForm, ich intialisiere dieses array im konstruktor was soweit auch sinn macht da die daten, im zur ganzen laufzeit erhalten bleiben sollen, mir kommts einfach so vor als ob der search slot myd[] garnicht kennt. obwohl er dies ja müsste ist ja ein attribut seiner class. daher macht mich das son bisschen ratlos ich wüsst halt nicht wie ich ihm das sonst sinnvoll übergeben könnte.
  5. Hallo omegano,

    darf man erfahren, welche Fehlermeldung Du wegen der Änderung des Konstruktors bekommst?
    Solange der Konstruktor so ist, wie er im ersten Posting ist, ist das auf jeden Fall falsch, da das Klassen-Attribut myd niemals initialisiert wird. Daher ist später myd == NULL und Du bekommst den Segmentation Fault.

    Beitrag zuletzt geändert: 19.5.2012 0:58:59 von darkpandemic
  6. Autor dieses Themas

    omegano

    omegano hat kostenlosen Webspace.

    xxx/CCWkoloDBbeta/mainForm.cpp:9: error: '=': 'Data **' kann nicht in 'Data *[]' konvertiert werden

    aber warum ist das array nicht initialsiert ich mache das doch mit getDatabase ? :o
  7. Hallo omegano,

    ändere mal die Klassendeklaration zu:
    class MForm : public QMainWindow, private Ui::MainWindow {
        Q_OBJECT
    public:
        Data** myd;
        MForm();
        ~MForm(){}
    protected slots:
        void search();
        void save();
    
    private:
        void getDatabase(Data* myd[]);
    };
    Dann funktioniert der Konstruktor.
    Nun die Erklärung:
    Du hast ein Klassen-Attribut mit Namen 'myd'. Im Konstruktor schreibst Du dann:
    Data* myd[LENGTH];
    Diese Zeile ist aber die Deklaration und Definition einer lokalen Variablen im Konstruktor. D.h. Du hast jetzt eigentlich zwei Variablen mit dem Namen 'myd'. Wenn Du jetzt im Code den Namen 'myd' verwendest wird die lokale Variable verwendent und nicht das Klassen-Attribut, da lokale Namen immer Vorrang vor Klassen-Attributen haben. Das Klassen-Attribut kannst Du jetzt nur noch mit 'this->myd' ansprechen.
    D.h. Du initialisierst eine lokale Variable, übergibst diese an getDatabase() und beim Verlassen des Konstruktors wird sie bereits wieder zerstört. Das Klassen-Attribut wurde nie angerührt.

    Edit: Ich sehe gerade, du kannst es Dir eigentlich noch einfacher machen:
    class MForm : public QMainWindow, private Ui::MainWindow {
        Q_OBJECT
    public:
        Data* myd[LENGTH];
        MForm();
        ~MForm(){}
    protected slots:
        void search();
        void save();
    
    private:
        void getDatabase(Data* myd[]);
    };
    Dann kannst Du im Konstruktor auf "myd = new Data*[LENGTH];" vollständig verzichten.




    Beitrag zuletzt geändert: 19.5.2012 1:47:16 von darkpandemic
  8. Autor dieses Themas

    omegano

    omegano hat kostenlosen Webspace.

    also das mit deiner initialisierung war aufjedenfall schonmal ein fehler. der andere fehler war
    das if() musste anders gestaltet werden.

    void MForm::search(){
        QString str = lineEdit->text();
        QString buf,temp;
        str=str.toLower();
        textEdit->clear();
        for(int i=0 ; i<LENGTH-1 ; i++){
            if(myd[i]!=NULL){
                if((myd[i]->owner.toLower()).indexOf(str)!= -1){
                    buf.clear();
                    buf=buf.setNum(myd[i]->gala)+":";
                    buf+=QString::number(myd[i]->system)+":";
                    buf+=QString::number(myd[i]->plani)+" / ";
                    buf+="von "+myd[i]->owner+"(Punkte: "+ QString::number(myd[i]->points) +" / AZ: "+QString::number(myd[i]->az)+")";
                    buf+=" Planetenname: "+myd[i]->name;
                    buf+=" / Allianz: "+myd[i]->alli+"\n";
                    temp=textEdit->toPlainText();
                    temp.append(buf);
                    textEdit->setPlainText(temp);
                }
            }
        }
    }


    Da es sonst sein kann das er nen toLower auf nen Attribut macht, wo der Zeiger ins Nirvana zeigt.

    Vielen dank für deine Hilfe ;)
  9. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!