Important: Please read the Qt Code of Conduct -

QtConcurrent: function object with qhash as member

  • Hi,

    I'm having some trouble with the QtConcurrent api. When I try to use a function object in the QtConcurrent::blockingMap function which contains a QHash as a member variable, my application crashes when i try to look up something in that qhash in the parallell call. My (little bit simplified) code looks like this:

    struct ParentChildFunctionObject
    	ParentChildFunctionObject(QHash<QUuid, QString> lookupHash)
    		: _lookupHash(lookupHash)
    	void operator()(const QUuid& guid)
              QHash<QUuid, QString>::iterator it = _lookupHash.find(guid)  //->  crash here
    	QHash<QUuid, QString> _lookupHash
    void ImportOperation::fillParentChildStructure()
    	QtConcurrent::blockingMap(_myListOfQUuids, ParentChildFunctionObject(_myLookupHash));
            //_myListOfQUuids is a QVector<QUuid> and _myLookupHash is a QHash<QUuid, QString>

    The crash occurs in the find method of the qhash (when I just assign a fixed value to the string i need, everything works fine).

    What am I missing?


    Ps: An alternative would be to give the string I need as an extra parameter in the blockingMap parallel called function. Is that possible?

    Pps: Qt 5.12, msvc2017 compiler, Win10, but i don't think it matters :)

  • Lifetime Qt Champion

    Since find() is done on a non-const QHash the first thing which is done is detach(). Since detach() itself is not thread-safe you will maybe get a crash here due to concurrency.
    When you don't modify the QHash I would pass it as const reference (this should be done in any case to avoid a copy) and store it as 'const QHash<QUuid, QString> _lookupHash' or even as 'QHash<QUuid, QString> &_lookupHash' so find() will work on a const container so it doesn't get detached.

  • That indeed seems to be the problem. After changing to const ref, it doesn't crash anymore.


Log in to reply