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

Remove QSharedPointer from a QList?



  • Good day QT'ers, wondering if there's a better way to remove a QSharedPointer from a QList loaded with them. Here's an example:

    void removeData()
    {
            QSharedPointer<DataPoints> dataPoint01(qobject_cast<DataPoints*>(sender()));
            // QList<QSharedPointer<DataPoints>> dataList;
            dataList.removeAll(dataPoint01);
    }
    

    This seems to crash when I run it in VS. I keep getting this error:
    Exception thrown: read access violation.
    this->ptr->**** was 0xFFFFFFFFFFFFFFE7.

    Any ideas? Appreciate the help, thank you!


  • Lifetime Qt Champion

    @Calicoder said in Remove QSharedPointer from a QList?:

    sender()

    Sender is a DataPoints?!
    I don't really understand this code snippet.
    removeData() seems to be a slot - is that right?
    If it is a slot who is emitting the signal (which class)?
    Does sender() return a valid pointer (you should always check pointers before using them!)?



  • @jsulm I see that I never do check if the sender does return a valid pointer, great idea. I'll add the check now. Thanks



  • Back to crashing when the dataList.removeAll(dataPoint01) is called. I added a if (!dataPoint01.isNull()) check like this:

    void removeData()
    {
            QSharedPointer<DataPoints> dataPoint01(qobject_cast<DataPoints*>(sender()));
            // QList<QSharedPointer<DataPoints>> dataList;
            if (!dataPoint01.isNull())
            {
                  dataList.removeAll(dataPoint01);
            }
    }
    

    The check works well and the dataPoint01 variable is not null. The sender is:

    void createDataPoint()
    {
    	QSharedPointer<DataPoints> newDataPoint(new DataPoints());
    	connect(newDataPoint.data(), &Class01::deleteDataPoint, this, &Class02::deleteDataPoint);
    	dataList.append(newDataPoint);
    }
    

    I get this error in VS:

    Exception thrown: read access violation.
    this->ptr->**** was 0xFFFFFFFFFFFFFFE7.
    What could be causing this?



  • @Calicoder said in Remove QSharedPointer from a QList?:

    Back to crashing when the dataList.removeAll(dataPoint01) is called. I added a if (!dataPoint01.isNull()) check like this:

    void removeData()
    {
            QSharedPointer<DataPoints> dataPoint01(qobject_cast<DataPoints*>(sender()));
            // QList<QSharedPointer<DataPoints>> dataList;
            if (!dataPoint01.isNull())
            {
                  dataList.removeAll(dataPoint01);
            }
    }
    

    The problem is that this code is creating a QSharedPointer from a raw pointer, which implies ownership of the object pointed to. When the last associated QSharedPointer goes out of scope, the object will be deleted. When removeData() returns, any further attempts to reference the sender is undefined behavior. This will also be a problem if the QObject was not allocated with new. Two QSharedPointers that happen to be initialized with the same raw pointer are not using the same reference count.

    template <typename X> QSharedPointer::QSharedPointer(X *ptr):

    The pointer ptr becomes managed by this QSharedPointer and must not be passed to another QSharedPointer object or deleted outside this object.
    


  • @jeremy_k Great explanation thank you. So it would seem passing the newly created DataPoints variable newDataPoint in createDataPoint() as a param in removeData() would be a better solution for this I'm thinking.



  • @Calicoder said in Remove QSharedPointer from a QList?:

    @jeremy_k Great explanation thank you. So it would seem passing the newly created DataPoints variable newDataPoint in createDataPoint() as a param in removeData() would be a better solution for this I'm thinking.

    That depends on how it's used. sender() isn't a problem as long as removeData() is called via a direct connection.


  • Lifetime Qt Champion

    Hi,

    Out of curiosity, why do you need QSharedPointer in this case ?


Log in to reply