Qt QString克隆分段故障 [英] Qt QString cloning Segmentation Fault

查看:356
本文介绍了Qt QString克隆分段故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Qt Creator构建我的第一个Qt应用程序,一切都进行得很顺利,直到我从一个行开始得到一个奇怪的SIGSEGV显然是无害的。

I'm building my first Qt app using Qt Creator, and everything was going fine until I started getting a strange SIGSEGV from a line apparently harmless.

错误:


程序接收信号SIGSEGV,分段故障。
0x0804e2fe in QBasicAtomicInt :: ref(this = 0x0)at /usr/lib/qt/include/QtCore/qatomic_i386.h:120

Program received signal SIGSEGV, Segmentation fault. 0x0804e2fe in QBasicAtomicInt::ref (this=0x0) at /usr/lib/qt/include/QtCore/qatomic_i386.h:120

通过回溯 gdb 上的异常,我发现一个简单的getter在返回我的属性时传递一个指向克隆构造函数的NULL指针。

By backtracing the exception on gdb, I found that a simple getter is passing a NULL pointer to the clone constructor when I return my attribute.

Backtrace输出:

Backtrace output:


(gdb)backtrace

#0 0x0804e2fe在QBasicAtomicInt :: ref(this = 0x0)at /usr/lib/qt/include/QtCore/qatomic_i386.h:120

#1 0x0804eb1b在QString(这= 0xbfcc8e48,其他= @ 0xbfcc8e80)在/usr/lib/qt/include/QtCore/qstring.h:712 < br>
#2 0x0805715e in Disciplina :: getId(this = 0xbfcc8e7c)at disciplina.cpp:13

[...]

(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构造函数的指针:

Inspecting the pointer passed to the QString constructor:


(gdb)x 0xbfcc8e80

0xbfcc8e80:0x00000000

(gdb) x 0xbfcc8e80
0xbfcc8e80: 0x00000000

这是disciplina.cpp:13

And this is disciplina.cpp:13

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

因此,所有指向QString的复制构造函数接收一个空指针对我来说没有意义。 id 被声明为私有QString。

So, all points towards the copy constructor of QString receiving an empty pointer, which makes no sense to me. id was declared as a private QString.

private:
    QString id;

好吧,我不知道可能发生什么,我的调试技能,所以如果有人可以提出一个想法,我会很高兴。

Well, I have no clue of what could be going on, and my debugging skills only go so far, so if anyone could throw an idea I'd be really glad.

谢谢。

编辑

根据要求提供更多代码。

More code, as requested.

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

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;
}

调用函数em>

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创建了一个vanilla值,它看起来就像对象在那里一样。

Solved

The Disciplina object inserted into the map was getting out of scope and therefore deleted. Since, as Jacinto pointed out, Map created a vanilla value when you try to access a nonexistent key, it looked like the object was there.

推荐答案

在c ++的地图中,如果元素不存在,当你尝试通过它的键访问它,它只是为你创建一个。你试图在这里做同样的事情,如果QMap工作方式相同,这是导致你的segfault。

In c++'s map, if the element doesn't exist when you try to access it by its key, it just creates one for you. You are attempting to do the same thing here, and if QMap works the same way, this is what is causing your segfault.

你应该做的是测试键在访问它之前在地图中。

What you should be doing is testing for the key's presence in the map before accessing it.

编辑:对于C ++纯粹主义者,请让我知道如果我有这个权利。我知道在实践中,在访问它之前测试更安全,但我不知道它为你创建一个的短语是否是一个很好的方式。它可能只是返回你在内存中的空间,这样的值将是;我不知道它是否会实际调用默认构造函数。

edit: for the C++ purists, please let me know if i have that right. I know in practice it's safer to test before accessing it, but I don't know if the phraseology of "it creates one for you" is a very good way to put it. It might just return you the space in memory where such a value would be; I don't know if it would actually call the default constructor.

这篇关于Qt QString克隆分段故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆