Pregunta

Estoy construyendo mi primera aplicación QT usando QT Creator, y todo iba bien hasta que comencé a obtener un extraño sigsegv de una línea aparentemente inofensivo.

Este es el error:

Programa recibió señal SigseGV, falla de segmentación. 0x0804e2fe en Qbasicatomicint :: ref (this = 0x0) AT /usr/lib/qt/include/qtcore/qatomic_i386.h:120

Retrocediendo la excepción en gdb, Descubrí que un Getter simple está pasando un puntero nulo al constructor de clonos cuando devuelve mi atributo.

Salida de retroceso:

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

Inspeccionar el puntero pasado al constructor QString:

(GDB) x 0xbfcc8e80
0xbfcc8e80: 0x00000000

Y esto es disciplina.cpp: 13

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

Entonces, todos los puntos hacia el constructor de copias de Qstring reciben un puntero vacío, lo que no tiene sentido para mí. identificación fue declarado como un QString privado.

private:
    QString id;

Bueno, no tengo idea de lo que podría estar sucediendo, y mis habilidades de depuración solo llegan tan lejos, así que si alguien pudiera arrojar una idea, estaría muy contento.

Gracias.

editar

Más código, según lo solicitado.

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

Función de la persona que llama (la rompí para una depuración más fácil)

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

Resuelto

los Disciplina El objeto insertado en el mapa estaba saliendo del alcance y, por lo tanto, se eliminaba. Dado que, como señaló Jacinto, Map creó un valor de vainilla cuando intenta acceder a una clave inexistente, parecía que el objeto estaba allí.

Gracias a los dos Jacinto y pata para su ayuda.

¿Fue útil?

Solución

En el mapa de C ++, si el elemento no existe cuando intenta acceder a él por su clave, simplemente crea uno para usted. Está intentando hacer lo mismo aquí, y si QMAP funciona de la misma manera, esto es lo que está causando su Segfault.

Lo que debería estar haciendo es probar la presencia de la clave en el mapa antes de acceder a ella.

EDITAR: Para los puristas de C ++, avíseme si tengo ese derecho. Sé en la práctica que es más seguro probar antes de acceder a él, pero no sé si la fraseología de "crea uno para ti" es una muy buena manera de decirlo. Podría devolverle el espacio en la memoria donde sería dicho valor; No sé si realmente llamaría al constructor predeterminado.

Otros consejos

Quizas el Disciplina objeto al que estás llamando getId() ON se eliminó previamente, para que ya no sea válido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top