我正在使用QT Creator构建我的第一个QT应用程序,并且一切顺利,直到我开始从一条无害的行中获得一个奇怪的Sigsegv。

这是错误:

程序收到信号sigsegv,分割故障。 0x0804e2fe in 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

这是纪律。CPP:13

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

因此,所有指向QString的复制构造函数都接收了一个空指针,这对我来说没有任何意义。 ID 被宣布为私人QString。

private:
    QString id;

好吧,我不知道会发生什么,而且我的调试技能只有这么远,所以如果有人能提出一个主意,我会感到非常高兴。

谢谢。

编辑

根据要求的更多代码。

纪律

#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

纪律

#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在尝试访问不存在的键时创建了一个香草价值,因此看起来像对象在那里。

谢谢你们俩 JacintoSTH 您的帮助。

有帮助吗?

解决方案

在C ++的映射中,如果您尝试通过其密钥访问它时不存在该元素,则它将为您创建一个。您正在尝试在这里做同样的事情,如果QMAP以相同的方式工作,这就是导致您的segfault的原因。

您应该做的是在访问它之前对密钥的存在进行测试。

编辑:对于C ++纯粹主义者,请让我知道我是否有正确。我知道在访问它之前测试要安全,但是我不知道“它为您创建一个”的措辞是否是一种很好的方法。它可能只是将您的内存中的空间返回,在内存中会有这样的值;我不知道它是否真的会调用默认构造函数。

其他提示

也许是 Disciplina 您正在调用的对象 getId() 以前已被删除,因此它不再有效。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top