Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QTableView SIGSEGV by repaint and destruction



  • Hi everybody,
    I am using a QTableView in my application for displaying some Information of E-Mails, which I want to analyze like shown in the screenshot below (in the second tab is currently no widget).
    upload.PNG

    Before importing the Mails by using Chilkat-Library, there are no Problems.

    After loading the data i get the following Problem:
    If I change the Tab of the QTabView-Widget from "Mail-Liste" to Mail-Struktur" (or if the "Mail-Struktur"-Tab was active before loading the mails by changing to "Mail-Liste") I get a Segmentation fault in "qvariant_p.h", line 173. The same problem occurs if i Quit the program.

    Here is the (shortened) sourcecode of my Model I use for the QTableView:

    cmaillistmode.h:

    #include <QAbstractTableModel>
    #include <QList>
    #include <QDebug>
    
    #include "cmail.h"
    
    /* DEFINES */
    #define MAIL_LIST_TABLE_NUM_COLUMNS 6
    
    class CMailListModel : public QAbstractTableModel
    {
        Q_OBJECT
    public:
        /* Konstruktor */
        CMailListModel();
    
        /* Destruktor */
        ~CMailListModel() override;
    
        /* Implementierung ehmals virtueller Funktionen */
        int rowCount(const QModelIndex &parent = QModelIndex()) const override;
        int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    
        /* Daten für Tabelle abfragen */
        QVariant headerData(int section, Qt::Orientation orientation, int role) const;
        QVariant data(const QModelIndex &index, int role) const;
    
        /* Neue E-Mail hinzufügen */
        void appendMail(CMail* pNewMail);
        void appendMailOnce(CMail* pNewMail); /* Mail nur hinzufügen, wenn noch nicht in System ( bei message-ID)*/
    
    private:
        QList<CMail*>*    m_pMailList;
    };
    
    #endif // CMAILLISTMODEL_H
    
    

    cmaillistmodel.cpp

    /* Modell für Darstellung und Abbildung der Liste aller geladenen / im Projekt enthaltenen Mails */
    
    #include "cmaillistmodel.h"
    
    CMailListModel::CMailListModel()
    {
        /* Neue Mailliste erstellen */
        this->m_pMailList = new QList<CMail*>;
    }
    
    /* Destruktor */
    CMailListModel::~CMailListModel()
    {
       /* Delete list with CMail-Objects */
        for(int i=0; i<m_pMailList->count(); i++)
        {
            qDebug() << "Removing mail " << m_pMailList->at(i)->subject();
            delete m_pMailList->at(i);
        }
        qDebug() << "All mails removed.";
    }
    
    /* Anzahl der Reihen / Spalten abfragen */
    int CMailListModel::rowCount(const QModelIndex &parent) const
    {
        return this->m_pMailList->count();
    }
    int CMailListModel::columnCount(const QModelIndex &parent) const
    {
        return MAIL_LIST_TABLE_NUM_COLUMNS;
    }
    
    /* Header abfragen */
    QVariant CMailListModel::headerData(int section, Qt::Orientation orientation, int role) const
    {
        if(role!=Qt::DisplayRole)
            return QVariant();
    
        if(orientation==Qt::Horizontal)
        {
            switch(section)
            {
                case 0:
                    return tr("#");
                case 1:
                    return tr("Zeitstempel");
                case 2:
                    return tr("Betreff");
                case 3:
                    return tr("Absender");
                case 4:
                    return tr("Message-ID");
                case 5:
                    return tr("Dep. Level");
                default:
                    return {};
            }
        }
    }
    
    /* Daten abfragen */
    QVariant CMailListModel::data(const QModelIndex &index, int role) const
    {
        if(role != Qt::DisplayRole && role!=Qt::EditRole)
            return {};
    
        CMail* pMail = this->m_pMailList->at(index.row());
    
        switch(index.column())
        {
            case 0:
                return QString("%1").arg(index.row());
            case 1:
                return QString(pMail->emailDateStr());
            case 2:
                return QString(pMail->subject());
            case 3:
                return QString(pMail->ck_from());
            case 4:
                return QString(pMail->getHeaderField("Message-ID"));
            case 5:
                return QString("%1").arg(pMail->calculateDependencyLevelBySubject());
            default:
                return {};
        }
    }
    
    /* Neue E-Mail- anhängen */
    void CMailListModel::appendMail(CMail *pNewMail)
    {
        if(pNewMail!=NULL)
        {
            beginInsertRows({}, m_pMailList->count(), m_pMailList->count());
            this->m_pMailList->append(pNewMail);
            qDebug() << "Appending mail " << pNewMail->subject();
            endInsertRows();
        }
    }
    
    /* Neue Mail anhängen, wenn Sie noch nicht im System ist (Abgleich der Message-ID) */
    void CMailListModel::appendMailOnce(CMail *pNewMail)
    {
        if(pNewMail!=NULL)
        {
            bool bMailExists=false;
            for(int i=0;i<m_pMailList->count(); i++)
            {
                QString strNewMessageID, strCurrentMessageID;
                strNewMessageID = QString(pNewMail->getHeaderField("Message-ID"));
                strCurrentMessageID = QString(m_pMailList->at(i)->getHeaderField("Message-ID"));
    
                if(strNewMessageID==strCurrentMessageID)
                {
                    bMailExists=true;
                    break;
                }
            }
            if(!bMailExists)
            {
                this->appendMail(pNewMail);
            }
        }
    }
    

    CMail-Class is derived from CkEmail (here are the references like here:

    class CMail : public CkEmail
    {
    public:
        /* Konstruktor */
        CMail();
    };
    

    The instance i use for processing the loaded mail-data is a member of my CMainWindow-Class. I set the model after creating the UI:

    CMainWindow::CMainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::CMainWindow)
    {
        /* Datenmodelle erzeugen */
        this->m_pMailListModel = new CMailListModel();
    
        ui->setupUi(this);
    
        /* Datenmodelle an Steuerelemente binden */
        ui->tblMailListView->setModel(this->m_pMailListModel);
    }
    

    And this is how it is destructed, but like i can see in my debug-output, if i quit the application, the CMainWindow-destructor is not called, the SIGSEGV occures before this.

    CMainWindow::~CMainWindow()
    {
        qDebug() << "Delete Mail-List-Model...";
        delete m_pMailListModel;
        qDebug() << "Mail-List-Model deleted.";
    
        qDebug() << "Delete UI...";
        delete ui;
        qDebug() << "UI deleted.";
    }
    

    I hope you have any idea how i can solve this problem.



  • I get a Segmentation fault in "qvariant_p.h", line 173

    Post the stack trace please

    QList<CMail*>* m_pMailList;

    You are leaking that variable, just allocate the list on the stack

    ~CMailListModel()

    just use qDeleteAll

    CMailListModel::rowCount / CMailListModel::columnCount

    They should return 0; if parent.isValid() otherwise it's an infinitely deep tree

    CMailListModel::data

    Passing an invalid index causes segfault

    CMailListModel::appendMail

    Takes ownership of the object, are you sure you are not deleting it from the calling method?



  • Thank you for the quick answer. I suggest, that the last thing you mentioned is where the failure occures, i will try to solve this (this is the point i notice that my last programming exercise is a few years ago).
    The other point i have fixed also, thank you for this.


Log in to reply