【发布时间】:2009-12-07 18:30:18
【问题描述】:
我正在使用 Qt Creator 构建我的第一个 Qt 应用程序,一切都很顺利,直到我开始从一条看似无害的线路中得到一个奇怪的 SIGSEGV。
这是错误:
程序收到信号SIGSEGV,分段错误。 /usr/lib/qt/include/QtCore/qatomic_i386.h:120 处的 QBasicAtomicInt::ref (this=0x0) 中的 0x0804e2fe
通过回溯 gdb 上的异常,我发现当我返回属性时,一个简单的 getter 将 NULL 指针传递给克隆构造函数。
回溯输出:
(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
这是 disciplina.cpp:13
QString Disciplina::getId()
{
return id;
}
所以,所有指向 QString 的复制构造函数接收一个空指针,这对我来说毫无意义。 id 被声明为私有 QString。
private:
QString id;
好吧,我不知道会发生什么,而且我的调试技能也只能到此为止,所以如果有人能提出一个想法,我会非常高兴。
谢谢。
编辑
根据要求提供更多代码。
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;
}
调用函数(我将其分解为便于调试)
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 在您尝试访问不存在的键时创建了一个普通值,所以看起来对象就在那里。
感谢 Jacinto 和 sth 的帮助。
【问题讨论】:
-
与我的回答相吻合, currentCurso->getDisciplinas()) 是什么类型?如果它不是相同类型的键/值的 QMap,那么这不起作用。此外,当您可以访问原始地图时,为什么要创建地图的值类型副本?你在做什么对我来说没有多大意义。
-
仅出于调试原因。我用一些冗余的方式分解了那里发生的所有事情,一次只踩一行。