Qt qstring klonierende Segmentierungsfehler
Frage
Ich baue meine erste QT -App mit QT Creator auf, und alles lief gut, bis ich anfing, ein seltsames Sigsegv aus einer Linie scheinbar harmlos zu bekommen.
Dies ist der Fehler:
Programm empfangenes Signal Sigsegv, Segmentierungsfehler. 0x0804e2fe in QBasicatomicint :: ref (this = 0x0) at /usr/lib/qt/include/qtcore/qatomic_i386.h:120
Durch Backverhalten der Ausnahme auf GDB, Ich fand, dass ein einfacher Getter einen Nullzeiger zum Klonkonstruktor übergibt, wenn ich mein Attribut zurückgibt.
Backtrace -Ausgabe:
(gdb) backtrace
#0 0x0804e2fe in QBasicAtomicInt::ref (this=0x0) at /usr/lib/qt/include/QtCore/qatomic_i386.h:120
#1 0x0804eb1b in QString (this=0xbfcc8e48, other=@0xbfcc8e80) at /usr/lib/qt/include/QtCore/qstring.h:712
#2 0x0805715e in Disciplina::getId (this=0xbfcc8e7c) at disciplina.cpp:13
[...]
Überprüfung des Zeigers, der an den Qstring -Konstruktor übergeht:
(GDB) x 0xBFCC8E80
0xBFCC8E80: 0x00000000
Und das ist Disziplina.cpp: 13
QString Disciplina::getId()
{
return id;
}
Alle Hinweise auf den Kopierkonstruktor von Qstring, der einen leeren Zeiger erhält, was für mich keinen Sinn macht. Ich würde wurde als privates Qstring deklariert.
private:
QString id;
Nun, ich habe keine Ahnung, was los sein könnte, und meine Debugging -Fähigkeiten gehen nur so weit. Wenn jemand eine Idee machen könnte, würde ich mich wirklich froh machen.
Vielen Dank.
bearbeiten
Weitere Code, wie angefordert.
Disziplina.h
#ifndef DISCIPLINA_H
#define DISCIPLINA_H
#include <QString>
#include <QMap>
#include "curso.h"
#include "turma.h"
class Curso;
class Turma;
class Disciplina
{
private:
unsigned short int serie;
QString id;
QString nome;
Curso* curso;
QMap<unsigned int, Turma*> turmas;
public:
Disciplina(QString id, Curso* curso, QString nome, unsigned short int serie);
QString getId();
const Curso getCurso();
QString getNome();
void setNome(QString nome);
void addTurma(Turma* t, unsigned int id);
QMap<unsigned int, Turma*> getTurmas();
};
#endif // DISCIPLINA_H
Disziplina.cpp
#include "disciplina.h"
Disciplina::Disciplina(QString id, Curso* curso, QString nome, unsigned short int serie)
{
this->id = id;
this->curso = curso;
this->nome = nome;
this->serie = serie;
}
QString Disciplina::getId()
{
return id;
}
const Curso Disciplina::getCurso()
{
const Curso c(*this->curso);
return c;
}
QString Disciplina::getNome()
{
return this->nome;
}
void Disciplina::setNome(QString nome)
{
this->nome = nome;
}
void Disciplina::addTurma(Turma* t, unsigned int id)
{
this->turmas.insert(id, t);
}
QMap<unsigned int, Turma*> Disciplina::getTurmas()
{
return this->turmas;
}
Anruferfunktion (ich habe es für einfacheres Debugging abgebrochen)
Disciplina*
MainWindow::getSelectedDisciplina()
{
if(ui->disciplinaTurma->count() > 0 && currentCurso)
{
QMap<QString, Disciplina*> qm(currentCurso->getDisciplinas());
QString key = ui->disciplinaTurma->itemText(ui->disciplinaTurma->currentIndex());
Disciplina* d = qm[key];
QMessageBox::information(this, d->getId(), d->getNome());
return d;
}
else
return NULL;
}
Gelöst
Das Disciplina
Das in die Karte eingefügte Objekt wurde aus dem Zielfernrohr ausgegangen und daher gelöscht. Da MAP, wie Jacinto betonte, einen Vanillewert erstellt hat, wenn Sie versuchen, auf einen nicht existierenden Schlüssel zuzugreifen, sah es so aus, als ob das Objekt dort war.
Danke euch beiden Jacinto und sth für deine Hilfe.
Lösung
Wenn das Element in der Karte von C ++ nicht vorhanden ist, wenn Sie versuchen, über seinen Schlüssel darauf zuzugreifen, erstellt es nur eine für Sie. Sie versuchen, das Gleiche hier zu tun, und wenn QMAP genauso funktioniert, ist dies das, was Ihren Segfault verursacht.
Was Sie tun sollten, ist das Testen der Präsenz des Schlüssels in der Karte, bevor Sie darauf zugreifen.
Bearbeiten: Für die C ++ - Puristen lassen Sie mich bitte wissen, ob ich das Recht habe. Ich weiß, dass es in der Praxis sicherer ist, vor dem Zugriff darauf zu testen, aber ich weiß nicht, ob die Ausdrucksform von "Es schafft eine für Sie" ein sehr guter Weg, um sie auszudrücken. Es könnte Sie nur den Speicherplatz im Speicher zurückgeben, in dem ein solcher Wert sein würde; Ich weiß nicht, ob es tatsächlich den Standardkonstruktor aufrufen würde.
Andere Tipps
Vielleicht der Disciplina
Objekt, das Sie anrufen getId()
auf wurde zuvor gelöscht, so dass es nicht mehr gültig ist.