سؤال

أقوم ببناء تطبيق QT الأول الخاص بي باستخدام Creator QT، وكان كل شيء على ما يرام حتى بدأت في الحصول على SigseGv غريب من خط غير ضار على ما يبدو.

هذا هو الخطأ:

تلقى البرنامج إشارة SIGSEGV، خطأ تجزئة. 0x0804E2FE في QBASICATOMICINT :: المرجع (هذا = 0x0) في /usr/lib/qt/include/qtcore/qatomic_i386.h:120

عن طريق تراكز الاستثناء GDB, لقد وجدت أن Getter بسيطة يمر مؤشر فارغ إلى منشئ الاستنساخ عندما أعود سمة بلدي.

إخراج Backtrace:

(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 تلقي مؤشر فارغ، مما لا معنى له. هوية شخصية أعلن ككبرينغ خاص.

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 تم إدراج الكائن المدرج في الخريطة من النطاق وبالتالي حذفه. منذ ذلك الحين، كما أشار جاسينتو، أنشأت الخريطة قيمة الفانيليا عند محاولة الوصول إلى مفتاح غير موجود، بدا الأمر وكأن الكائن كان هناك.

شكرا لكما جاكينتو و سهم لمساعدتك.

هل كانت مفيدة؟

المحلول

في خريطة C ++، إذا لم يكن العنصر موجودا عند محاولة الوصول إليه بمفتاحه، فهذا فقط يخلق واحدا لك. أنت تحاول أن تفعل الشيء نفسه هنا، وإذا كان QMAP يعمل بنفس الطريقة، فهذا هو ما يسبب Segfault الخاص بك.

ما يجب أن تفعله هو اختبار وجود المفتاح في الخريطة قبل الوصول إليه.

تحرير: لأخصائيي C ++، واسمحوا لي أن أعرف إذا كان لدي هذا الحق. أعلم في الممارسة العملية أنه أكثر أمانا لاختبار قبل الوصول إليها، لكنني لا أعرف ما إذا كانت عبارة "إنهاء" إنه يخلق أحد من أجلك "هو وسيلة جيدة جدا لوضعها. قد يعيدك فقط المساحة في الذاكرة حيث تكون هذه القيمة؛ لا أعرف إذا كان سيتصل بالفعل بالبناء الافتراضي.

نصائح أخرى

ربما Disciplina الكائن الذي تتصل به getId() تم حذفها مسبقا، بحيث لا يكون صالحا بعد الآن.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top