문제

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은 이전에 삭제되었으므로 더 이상 유효하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top