Domanda

sto costruendo la mia prima applicazione Qt usando Qt Creator, e tutto stava andando bene fino a quando ho cominciato ad avere una strana SIGSEGV da una linea apparentemente innocua.

Questo è l'errore:

  

Programma ricevuto SIGSEGV segnale, Segmentation fault.   0x0804e2fe in QBasicAtomicInt :: ref (questo = 0x0) a /usr/lib/qt/include/QtCore/qatomic_i386.h:120

Con l'eccezione backtracing su gdb , ho scoperto che un semplice getter sta passando un puntatore NULL al costruttore clone quando torno il mio attributo.

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

Controllo del puntatore passato al costruttore QString:

  

(gdb) x 0xbfcc8e80
  0xbfcc8e80: 0x00000000

E questo è disciplina.cpp: 13

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

Quindi, tutti i punti verso il costruttore di copia di QString che ricevono un puntatore vuoto, che non ha senso per me. id è stato dichiarato come QString privato.

private:
    QString id;

Beh, non ho idea di quello che potrebbe essere in corso, e le mie capacità di debug solo andare così lontano, quindi se qualcuno potrebbe gettare un'idea sarei davvero contento.

Grazie.

modifica

Più codice, come richiesto.

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

funzione chiamante (ho rotto verso il basso per facilitare il debug)

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

Risolto

L'oggetto Disciplina inserita nella mappa è stata sempre fuori portata, e quindi eliminato. Dal momento che, come ha sottolineato Jacinto, una mappa creata un valore di vaniglia quando si tenta di accedere a una chiave inesistente, sembrava che l'oggetto era lì.

Grazie ad entrambi Jacinto e qc per il vostro aiuto.

È stato utile?

Soluzione

In C ++ 's carta, se l'elemento non esiste quando si tenta di accedere dal suo tasto, si crea solo uno per voi. Si sta tentando di fare la stessa cosa qui, e se QMap funziona allo stesso modo, questo è ciò che sta causando il vostro segfault.

Che cosa si dovrebbe fare è il test per la presenza della chiave nella mappa prima di accedervi.

modifica: per il C ++ puristi, per favore fatemelo sapere se ho questo diritto. So che, in pratica, è più sicuro di testare prima di accedervi, ma non so se la fraseologia di "uno crea per voi" è un ottimo modo per metterlo. Si potrebbe semplicemente si torna lo spazio in memoria in cui tale valore sarebbe; Non so se sarebbe davvero chiamare il costruttore di default.

Altri suggerimenti

Forse l'oggetto Disciplina si sta chiamando getId() è stato eliminato in precedenza, in modo che non è più valido.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top