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

Read access violation when creating model from QAbstractItemModel



  • Hi,

    I'm trying to create my model from QAbstractItemModel. Here is the code
    h5model.h:

    #ifndef H5MODEL_H
    #define H5MODEL_H
    
    #include <QAbstractItemModel>
    #include <QVector>
    
    #include "h5item.h"
    
    class H5Model : public QAbstractItemModel
    {
        Q_OBJECT
    public:
        explicit H5Model(QObject *parent = nullptr);
        ~H5Model();
    
        QModelIndex index(int row, int column, const QModelIndex &parent) const;
        QModelIndex parent(const QModelIndex &child) const;
    
        int rowCount(const QModelIndex &parent) const;
        int columnCount(const QModelIndex &parent) const;
    
        QVariant data(const QModelIndex &index, int role) const;
    
        QVariant headerData(int section, Qt::Orientation orientation, int role) const;
    
        bool canFetchMore(const QModelIndex &parent) const;
        void fetchMore(const QModelIndex &parent);
    
        bool hasChildren(const QModelIndex &parent) const;
    
    private:
        enum Columns
        {
            RamificationColumn,
            NameColumn = RamificationColumn,
            ModificationDateColumn,
            SizeColumn,
            TypeColumn,
            ColumnCount
        };
    
        H5Item item;
        typedef QVector<H5Item> itemList;
        itemList _items;
        void fetchRootDirectory();
        int findRow(const H5Item* nodeInfo) const;
    };
    
    #endif // H5MODEL_H
    
    

    h5model.cpp:

    #include "h5model.h"
    
    #include <highfive/H5File.hpp>
    #include <highfive/H5Group.hpp>
    #include <highfive/H5DataSet.hpp>
    #include <highfive/H5DataSpace.hpp>
    #include <highfive/H5Attribute.hpp>
    
    using namespace HighFive;
    
    H5Model::H5Model(QObject *parent) :
        QAbstractItemModel(parent)    // HERE I GET THE ERROR
    {
        fetchRootDirectory();
    }
    
    H5Model::~H5Model()
    {}
    
    QModelIndex H5Model::index(int row, int column, const QModelIndex &parent) const
    {
        if (!hasIndex(row, column, parent)) {
            return QModelIndex();
        }
    
        if (!parent.isValid()) { // запрашивают индексы корневых узлов
            Q_ASSERT(_items.size() > row);
            return createIndex(row, column, const_cast<H5Item*>(&_items[row]));
        }
    
        H5Item* parentInfo = static_cast<H5Item*>(parent.internalPointer());
        Q_ASSERT(parentInfo != nullptr);
        Q_ASSERT(parentInfo->mapped);
        Q_ASSERT(parentInfo->children.size() > row);
        return createIndex(row, column, &parentInfo->children[row]);
    }
    
    QModelIndex H5Model::parent(const QModelIndex &child) const
    {
        if (!child.isValid()) {
            return QModelIndex();
        }
    
        H5Item* childInfo = static_cast<H5Item*>(child.internalPointer());
        Q_ASSERT(childInfo != 0);
        H5Item* parentInfo = childInfo->parent;
        if (parentInfo != 0) {
            return createIndex(findRow(parentInfo), RamificationColumn, parentInfo);
        }
        else {
            return QModelIndex();
        }
    }
    
    int H5Model::findRow(const H5Item *nodeInfo) const
    {
        Q_ASSERT(nodeInfo != nullptr);
        const itemList& parentInfoChildren = nodeInfo->parent != 0 ? nodeInfo->parent->children: _items;
        itemList::const_iterator position = qFind(parentInfoChildren, *nodeInfo);
        Q_ASSERT(position != parentInfoChildren.end());
        return std::distance(parentInfoChildren.begin(), position);
    }
    
    int H5Model::rowCount(const QModelIndex &parent) const
    {
        if (!parent.isValid()) {
            return _items.size();
        }
        const H5Item* parentInfo = static_cast<const H5Item*>(parent.internalPointer());
        Q_ASSERT(parentInfo != nullptr);
    
        return parentInfo->children.size();
    }
    
    bool H5Model::hasChildren(const QModelIndex &parent) const
    {
        if (parent.isValid()) {
            const H5Item* parentInfo = static_cast<const H5Item*>(parent.internalPointer());
            Q_ASSERT(parentInfo != nullptr);
            if (!parentInfo->mapped) {
                return true;//QDir(parentInfo->fileInfo.absoluteFilePath()).count() > 0;
            }
        }
        return QAbstractItemModel::hasChildren(parent);
    }
    
    int H5Model::columnCount(const QModelIndex &parent) const
    {
        Q_UNUSED(parent)
        return ColumnCount;
    }
    
    QVariant H5Model::data(const QModelIndex &index, int role) const
    {
        if (!index.isValid()) {
            return QVariant();
        }
    
        const H5Item* nodeInfo = static_cast<H5Item*>(index.internalPointer());
        Q_ASSERT(nodeInfo != nullptr);
        return nodeInfo->itemShortName;
    }
    
    QVariant H5Model::headerData(int section, Qt::Orientation orientation, int role) const
    {
        const QStringList headers = {"Name"};
        if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section < headers.size()) {
            return headers[section];
        }
        return QVariant();
    }
    
    bool H5Model::canFetchMore(const QModelIndex &parent) const
    {
        if (!parent.isValid()) {
            return false;
        }
    
        const H5Item* parentInfo = static_cast<const H5Item*>(parent.internalPointer());
        Q_ASSERT(parentInfo != 0);
        return !parentInfo->mapped;
    }
    
    void H5Model::fetchMore(const QModelIndex &parent)
    {
    }
    
    void H5Model::fetchRootDirectory()
    {
        HighFive::File h5File("D:/DATA/seismic/raw_le.h5", File::ReadOnly);
        item = H5Item(h5File);
        _items.push_back(item);
    }
    
    

    I get the following error (I commented the line where I get this error, it is in class constructor):
    Exception at 0x7fff18e0f621, code: 0xc0000005: read access violation at: 0x0, flags=0x0 (first chance)
    b2de3590-c387-4885-b390-71dfa8007905-image.png
    After that I get:
    20402c21-cc52-42b6-903b-c38d2c046a3c-image.png
    I hope somebody could tell me where to start searching the error reason



  • I'm slowpoke
    The problem was in using QAlgorithms in the line:

    int H5Model::findRow(const H5Item *nodeInfo) const
    {
        const itemList& parentInfoChildren = nodeInfo->parent != nullptr ? nodeInfo->parent->children: _items;
        itemList::const_iterator position = qFind(parentInfoChildren, *nodeInfo); // *nodeInfo leads to error!!! just remove it and it works
        return std::distance(parentInfoChildren.begin(), position);
    }
    


  • I've found a mistake.
    I used to declare my items as:

    H5Item::H5Item(const HighFive::File& file, H5Item* parent) :
        parentFile(nullptr) // here is the error
    {
    }
    

    But now I have the following error:
    C2679: binary '==': no operator found which takes a right-hand operand of type 'const T' (or there is no acceptable conversion) with [T=H5Item]
    could be 'bool operator ==(const QStorageInfo &,const QStorageInfo &)'
    Here is my item header:

    #ifndef H5ITEM_H
    #define H5ITEM_H
    
    #include <QtCore>
    
    #include <highfive/H5File.hpp>
    #include <highfive/H5Group.hpp>
    #include <highfive/H5DataSet.hpp>
    #include <highfive/H5DataSpace.hpp>
    #include <highfive/H5Attribute.hpp>
    
    using namespace HighFive;
    
    
    class H5Item
    {
    public:
        H5Item(const HighFive::File& file, H5Item* parent = nullptr);
        H5Item(const HighFive::File& file, const HighFive::Group& group, H5Item* parent = nullptr);
        H5Item(const HighFive::File& file, const HighFive::DataSet& dataset, H5Item* parent = nullptr);
    
        QString itemFullName, itemShortName;
        HighFive::File parentFile;
        QVector<H5Item*> children;
        H5Item* parent;
    
        bool mapped;
    
        bool operator ==(const H5Item& another) const
        {
            bool r = this->itemFullName == another.itemFullName;
            return r;
        }
    };
    
    #endif // H5ITEM_H
    
    

  • Qt Champions 2019

    @Please_Help_me_D said in Read access violation when creating model from QAbstractItemModel:

    C2679: binary '==': no operator found which takes a right-hand operand of type 'const T

    Can you show the code where you get this error?
    Also, did you try complete rebuild?



  • @jsulm thank you for reply.
    The error I get on the compilation step. Also I don't use this operator, I think that QAbstractItemModel internally uses this operator.
    I've tried to clean the project then use QMake and build againg. That doesn't help.
    Actually my model is based on the example wich is uploaded here
    The main difference in the working example and my code is in the items of model.
    The example declare items as:

    struct FilesystemModel::NodeInfo
    {
    	NodeInfo():
    		parent(0),
    		mapped(false)
    	{}
    
    	NodeInfo(const QFileInfo& fileInfo, NodeInfo* parent = 0):
    		fileInfo(fileInfo),
    		parent(parent),
    		mapped(false)
    	{}
    
        bool operator ==(const NodeInfo& another) const
        {
            bool r = this->fileInfo == another.fileInfo;
            Q_ASSERT(!r || this->parent == another.parent);
            Q_ASSERT(!r || this->mapped == another.mapped);
            Q_ASSERT(!r || this->children == another.children);
            return r;
        }
    
    	QFileInfo fileInfo;
    	QVector<NodeInfo> children;
    	NodeInfo* parent;
    
    	bool mapped;
    };
    

    And I do that as (h5Item.cpp):

    #include "h5item.h"
    
    H5Item::H5Item(const HighFive::File& file, H5Item* parent) :
        parentFile(file),
        parent(parent),
        mapped(false)
    {
        itemFullName = file.getPath().c_str();
        itemShortName = file.getName().c_str();
    }
    
    H5Item::H5Item(const HighFive::File& file, const HighFive::Group& group, H5Item* parent) :
        parentFile(file),
        parent(parent),
        mapped(false)
    {
        itemFullName = group.getPath().c_str();
        itemShortName = itemFullName.mid(itemFullName.lastIndexOf("/"));
    }
    
    H5Item::H5Item(const HighFive::File& file, const HighFive::DataSet& dataset, H5Item* parent) :
        parentFile(file),
        parent(parent),
        mapped(false)
    {
        itemFullName = dataset.getPath().c_str();
        itemShortName = itemFullName.mid(itemFullName.lastIndexOf("/"));
    }
    
    


  • I'm slowpoke
    The problem was in using QAlgorithms in the line:

    int H5Model::findRow(const H5Item *nodeInfo) const
    {
        const itemList& parentInfoChildren = nodeInfo->parent != nullptr ? nodeInfo->parent->children: _items;
        itemList::const_iterator position = qFind(parentInfoChildren, *nodeInfo); // *nodeInfo leads to error!!! just remove it and it works
        return std::distance(parentInfoChildren.begin(), position);
    }
    

Log in to reply