QT übergabe eines Objektarrays an einen slot?
lima-city → Forum → Programmiersprachen → C/C++ und D
abfrage
allianz
array
attribut
code
datei
datum
deklaration
fehler
gala
klasse
machen
null
objekt
point
problem
programm
sinn
system
vermutung
-
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); } } } }
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
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:
Im Destruktor musst Du das Array mitMForm::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()) ); }
wieder freigeben.delete[] myd;
Als zweites prüfst Du im Slot search() nicht ob myd[ i ] == NULL ist, was die nächste Fehlerquelle ist. Also probiere mal folgendes:
Ich denke, damit sollte es dann gehen.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); } } }
Beitrag zuletzt geändert: 18.5.2012 20:17:00 von darkpandemic -
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. -
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 -
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 -
Hallo omegano,
ändere mal die Klassendeklaration zu:
Dann funktioniert der Konstruktor.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[]); };
Nun die Erklärung:
Du hast ein Klassen-Attribut mit Namen 'myd'. Im Konstruktor schreibst Du dann:
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.Data* myd[LENGTH];
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:
Dann kannst Du im Konstruktor auf "myd = new Data*[LENGTH];" vollständig verzichten.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[]); };
Beitrag zuletzt geändert: 19.5.2012 1:47:16 von darkpandemic -
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 ;) -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage