abergmeier
abergmeier

Reputation: 14052

QFutureIterator::next segfaults

I have the following Qt code, which segfaults in next(). I looked into the QtConcurrent code and it is not obvious to me, why it fails.

namespace {
    std::tuple<QString, std::exception_ptr> test( const int& data ) {
        return std::make_tuple( QString(), std::exception_ptr() );
    }
}

void
start() {
    QVector<int> downloadList;
    downloadList.push_back( 1 );
    downloadList.push_back( 2 );

    auto future = QtConcurrent::mapped( downloadList, test );

    QFutureIterator<std::tuple<QString, std::exception_ptr>> it( future );
    while( it.hasNext() ) {
        auto& tuple = it.next();
    }
}

The point it fails is:

const T *pointer() const
{
    if (mapIterator.value().isVector())
->      return &(reinterpret_cast<const QVector<T> *>(mapIterator.value().result)->at(m_vectorIndex));
    else
        return reinterpret_cast<const T *>(mapIterator.value().result);
}

Update:

The same crash for QFuture::const_iterator.


Note:

If I can believe GDB, this in QVector::at is 0x0. Then I assume that mapIterator.value().result already is a nullptr, why, I have no idea.

Upvotes: 1

Views: 151

Answers (1)

abergmeier
abergmeier

Reputation: 14052

Seems like the Qt4 docs are wrong, yet again (anyone surprised?). At least I could not find a reference to a waitForResult( int ) call in the iterators.

What does work though is using resultAt directly.

So you would replace

for( auto it = future.begin(); it != future.end(); ++it ) {
    auto& result = *it;

with

for( int i = 0; i != count; ++i ) {
    auto result = future.resultAt( i );

to prevent it from crashing.

Upvotes: 1

Related Questions