QT QSTRING 클로닝 세그먼테이션 오류
문제
QT Creator를 사용하여 첫 번째 QT 앱을 구축하고 있으며 분명히 무해한 라인에서 이상한 SIGSEGV를 얻기 시작할 때까지 모든 것이 잘 진행되었습니다.
이것은 오류입니다.
프로그램 수신 신호 SIGSEGV, 세그먼테이션 오류. 0x0804e2fe at qbasicatomicint :: ref (this = 0x0) at /usr/lib/qt/include/qtcore/qatomic_i386.h:120
예외를 역 추적하여 GDB, 나는 간단한 getter가 속성을 반환 할 때 클론 생성자에게 널 포인터를 전달한다는 것을 알았습니다.
백트레이스 출력 :
(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
[...]
QSTRING 생성자에게 전달 된 포인터 검사 :
(GDB) x 0xBFCC8E80
0xBFCC8E80 : 0x00000000
그리고 이것은 DICLINA.CPP : 13입니다
QString Disciplina::getId()
{
return id;
}
따라서 빈 포인터를 수신하는 Qstring의 사본 생성자를 향한 모든 점은 나에게 의미가 없습니다. ID 개인 QSTRING으로 선언되었습니다.
private:
QString id;
글쎄, 나는 무슨 일이 일어나고 있는지에 대한 단서가 없으며, 내 디버깅 기술은 지금까지만 진행되므로 누군가가 아이디어를 던질 수 있다면 정말 기뻐할 것입니다.
감사.
편집하다
요청에 따라 더 많은 코드.
DICLINA.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
DICLINA.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;
}
발신자 기능 (더 쉽게 디버깅을 위해 파산했습니다)
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;
}
해결되었습니다
그만큼 Disciplina
맵에 삽입 된 물체는 범위에서 벗어나서 삭제되었습니다. Jacinto가 지적했듯이 Map은 존재하지 않는 키에 액세스하려고 할 때 바닐라 값을 만들었으므로 객체가있는 것처럼 보였습니다.
둘 다 감사합니다 자킨토 그리고 STH 너의 도움으로.
해결책
C ++의 맵에서, 요소가 키로 액세스하려고 할 때 요소가 존재하지 않으면, 그것은 당신을 위해 하나를 만듭니다. 당신은 여기서 똑같은 일을하려고 시도하고 있으며, QMAP가 같은 방식으로 작동한다면 이것이 Segfault의 원인입니다.
당신이해야 할 일은 맵에서 키의 존재를 테스트하는 것입니다.
편집 : C ++ 순수 주의자의 경우 제가 그 권리가 있는지 알려주십시오. 실제로 액세스하기 전에 테스트하는 것이 더 안전하다는 것을 알고 있지만, "당신을 위해 하나를 만들어 낸다"라는 문구가 그것을 넣는 아주 좋은 방법인지는 모르겠습니다. 그러한 가치가있는 곳에서 메모리에 공간을 돌려 줄 수 있습니다. 실제로 기본 생성자를 호출 할 것인지 모르겠습니다.
다른 팁
아마도 Disciplina
당신이 부르는 대상 getId()
ON은 이전에 삭제되었으므로 더 이상 유효하지 않습니다.