Qt qstring cloning segmentação falha
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.
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.