ASSERT: "!data || data->ref.load() >= 1" in file image\qpixmap.cpp, line 273



  • Hi, friend. I opened a lot of images at once. and then,passed these image paths to some subclass QRunnable to read data. like below snippet code.

        for(int i=0; i<ltfilesPath.size(); i++){
            task = new CreateItemTask(ltfilesPath[i]);
            connect(task,&CreateItemTask::SigCreateItemTaskFinished,
                    this,&MainWindow::StCreateItemTaskFinished);
            _threadPool->start(task);
        }
    

    about my CreateItemTask class, like below code snippet:

    TEITEMTASK_H
    #define CREATEITEMTASK_H
    #include <QtCore/QRunnable>
    #include <QtCore/QObject>
    
    class CreateItemTask : public QObject, public QRunnable
    {
        Q_OBJECT
    public:
        CreateItemTask(const QString &filePath,QObject *parent = Q_NULLPTR);
        ~CreateItemTask();
    
        void run() override;
    
    signals:
        void SigCreateItemTaskFinished(void* item);
    
    private:
        QString     _filePath;
    };
    
    #endif // CREATEITEMTASK_H
    
    
    #include "itemtask.h"
    /** some include here ... */
    
    CreateItemTask::CreateItemTask(const QString &filePath, QObject *parent)
        :QObject(parent),QRunnable()
    {
        _filePath = filePath;
        setAutoDelete(true);
    }
    
    CreateItemTask::~CreateItemTask()
    {
    }
    
    void CreateItemTask::run()
    {
        /** some declare here */
    
        if(!ReadPixmap(_filePath,pixmap)){ /// this function code at below.
            return;
        }
    
        pItem = new QListWidgetItem;
        /** iterm set some data at here... */
    
        /** some code here.... */
    
        emit SigCreateItemTaskFinished((void*)pItem);
    }
    
    

    ReadPixmap Function.

    bool ReadPixmap(QString qsFilePath, QPixmap &pixmap)
    {
        /** some declare here... */
        if(!pixmap.load(qsFilePath)){ ///< Note here...
            reader.setFileName(qsFilePath);
            reader.setDecideFormatFromContent(true);
            if(!reader.canRead()){
                return false;
            }
    
            image = reader.read();
            if(image.isNull()){
                return false;
            }
    
            pixmap = QPixmap::fromImage(image);
            if(pixmap.isNull()){
                return false;
            }
    
        }
        return true;
    }
    

    sometime, pixmap.load(qsFilePath) some image can read crashed, and putout

    ASSERT: "!data || data->ref.load() >= 1" in file image\qpixmap.cpp, line 273

    What's wrong i did? and How to work it out?


  • Moderators

    @joeQ said in ASSERT: "!data || data->ref.load() >= 1" in file image\qpixmap.cpp, line 273:

    if(!ReadPixmap(_filePath,pixmap))

    Where is pixmap declared? Did you check all the images you're trying to load? Maybe some of them are broken?


  • Qt Champions 2016

    You can't use pixmaps from different threads, you need to switch to QImage when doing multithreading.



  • @kshegunov

    Thank you very much.

    I modified the function to

    bool ReadPixmap(QString qsFilePath, QPixmap &pixmap)
    {
        /** some declare at here */
    
        reader.setFileName(qsFilePath);
        reader.setDecideFormatFromContent(true);
        if(!reader.canRead()){
            return false;
        }
    
        image = reader.read();
        if(image.isNull()){
            return false;
        }
    
        pixmap = QPixmap::fromImage(image);
        if(pixmap.isNull()){
            return false;
        }
    
        return true;
    

    It worked.


  • Qt Champions 2016

    You still have a problem as you're creating, accessing and modifying widgets and pixmaps from different threads. QWidget and QPixmap are not reentrant, meaning you can create and access them only from the GUI thread.

    pItem = new QListWidgetItem;
    

    and

    pixmap = QPixmap::fromImage(image);
    

    are the offending lines. You need to modify everything in such a way that the widget creation and the pixmap conversion are done in the GUI thread; namely inside MainWindow::StCreateItemTaskFinished, not in the runnable's implementation.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.