Pergunta

Estou construindo meu primeiro aplicativo QT usando o QT Creator, e tudo estava indo bem até que eu comecei a conseguir um Sigsegv estranho de uma linha aparentemente inofensiva.

Este é o erro:

Programa recebeu sinal Sigsegv, falha de segmentação. 0x0804e2fe em qbasicatomicint :: ref (this = 0x0) em /usr/lib/qt/include/qtcore/qatomic_i386.h:120

Voltando a exceção em GDB, Descobri que um simples getter está passando um ponteiro nulo para o construtor do clone quando eu retorno meu atributo.

Saída de 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
[...]

Inspecionando o ponteiro passou para o construtor QString:

(GDB) x 0xbfc8e80
0xbfcc8e80: 0x00000000

E isso é disciplina.cpp: 13

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

Portanto, tudo aponta para o construtor de cópias do QString que recebe um ponteiro vazio, o que não faz sentido para mim. Eu iria foi declarado como um QString privado.

private:
    QString id;

Bem, eu não tenho idéia do que poderia estar acontecendo, e minhas habilidades de depuração só vão tão longe; portanto, se alguém pudesse dar uma idéia, eu ficaria muito feliz.

Obrigado.

editar

Mais código, conforme 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;
}

Função de chamadas (eu a quebrei para mais facilmente depuração)

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

Resolvido

o Disciplina O objeto inserido no mapa estava saindo do escopo e, portanto, excluído. Desde que, como Jacinto apontou, o MAP criou um valor de baunilha quando você tenta acessar uma chave inexistente, parecia que o objeto estava lá.

Obrigado a ambos Jacinto e sth para sua ajuda.

Foi útil?

Solução

No mapa de C ++, se o elemento não existir quando você tentar acessá -lo por sua chave, ele apenas cria um para você. Você está tentando fazer a mesma coisa aqui e, se o QMAP funcionar da mesma maneira, é isso que está causando seu segfault.

O que você deve fazer é testar a presença da chave no mapa antes de acessá -la.

EDIT: Para os puristas do C ++, informe -me se eu tiver isso direito. Sei que, na prática, é mais seguro testar antes de acessá -lo, mas não sei se a fraseologia de "Crie um para você" é uma maneira muito boa de colocá -lo. Pode apenas devolver o espaço na memória onde esse valor seria; Não sei se ele realmente chamaria o construtor padrão.

Outras dicas

Talvez o Disciplina objeto que você está chamando getId() On foi excluído anteriormente, para que não seja mais válido.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top