Question

Je construis ma première application Qt en utilisant Qt Creator, et tout allait bien jusqu'à ce que je commencé à obtenir un SIGSEGV étrange d'une ligne apparemment inoffensive.

Ceci est l'erreur:

  

Programme signal reçu SIGSEGV, Segmentation fault.   0x0804e2fe dans Réf QBasicAtomicInt (ce = 0x0) à /usr/lib/qt/include/QtCore/qatomic_i386.h:120

Par l'exception sur un tracé rétrograde gdb , j'ai trouvé qu'un getter simple, passe un pointeur NULL au constructeur clone quand je retourne mon attribut.

sortie Backtrace:

  

(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
  [...]

le pointeur passé Inspecter au constructeur QString:

  

(gdb) x 0xbfcc8e80
  0xbfcc8e80: 0x00000000

Et voici disciplina.cpp: 13

QString Disciplina::getId()
{
    return id;
}

Alors, tous les points vers le constructeur de copie de QString recevant un pointeur vide, ce qui en fait aucun sens pour moi. id a été déclarée comme QString privé.

private:
    QString id;

Eh bien, je n'ai aucune idée de ce qui pourrait se passer, et mes compétences de débogage aller seulement à ce jour, donc si quelqu'un pouvait jeter une idée que je serais vraiment heureux.

Merci.

modifier

code plus, comme l'a demandé.

disciplina.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

disciplina.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;
}

fonction de l'appelant (je l'ai cassé vers le bas pour le débogage plus facile)

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;
}

Résolu

L'objet Disciplina inséré dans la carte était de sortir du champ d'application et, par conséquent supprimé. Depuis, comme Jacinto a fait remarquer, Carte créé une valeur de vanille lorsque vous essayez d'accéder à une clé inexistante, il semblait que l'objet était là.

Merci à vous deux Jacinto et STH pour votre aide.

Était-ce utile?

La solution

Dans c ++ la carte de ', si l'élément n'existe pas lorsque vous essayez d'y accéder par sa clé, il crée juste pour vous. Vous essayez de faire la même chose ici, et si QMap fonctionne de la même façon, c'est ce qui cause votre segfault.

Ce que vous devez faire est de tester pour la présence de la clé sur la carte avant d'y accéder.

edit: pour les C ++ puristes, s'il vous plaît laissez-moi savoir si j'ai ce droit. Je sais que dans la pratique, il est plus sûr de tester avant d'y accéder, mais je ne sais pas si la phraséologie de « l'un crée pour vous » est une très bonne façon de le mettre. Il pourrait bien vous retourner l'espace mémoire où une telle valeur serait; Je ne sais pas si ce serait en fait appeler le constructeur par défaut.

Autres conseils

Peut-être l'objet Disciplina que vous appelez getId() sur précédemment supprimé, de sorte qu'il ne sera plus valable.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top