首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在QList上使用QtConcurrent::map()函数生成分段错误

在QList上使用QtConcurrent::map()函数生成分段错误
EN

Stack Overflow用户
提问于 2020-06-01 02:09:54
回答 1查看 212关注 0票数 0

我正在熟悉QtConcurrent库。我有一个UI (MainWindow),在这里我运行我的函数来模拟一个真实的多线程示例。

我使用的QtConcurrent::map()函数需要一些:

  1. Iterator或序列,在我的例子中,我使用的是QList
  2. 此外,它需要一个MapFunctor (它支持lambdas*),但为此,我选择使用静态方法进行测试。

我已经尝试过的

我尝试使用这两个map()函数(第一个未注释)

我试着搜索一个序列和一个MapFunctor,但是我只能在模板中找到它,这对我没有多大帮助,所以我不得不尝试用我的直觉来理解它。

代码:

在我MainWindow.cpp的某个地方

代码语言:javascript
复制
// counter variable stored in MainWindow
int i = 0;

// MapFunctor
void mapSumToQString(QPair<int, int> pair)
{
    i++;
    qDebug() << "Execute " << i << " = " << QString::number(pair.first, pair.second);;
}

以及启动这一切的代码

代码语言:javascript
复制
// UI class decl
MainWindow::MainWindow(QWidget* parent)
     : QMainWindow(parent)
     , ui(new Ui::MainWindow)
{
     ui->setupUi(this);

     // Create list of integers to perform map function on (here I don't write back to the original sequence i.e. list)
     QList<QPair<int, int>> intPairList = QList<QPair<int, int>>();
     for (int i = 0; i < 1000; i++) {
         int i1 = qrand();
         int i2 = qrand();
         intPairList.append(QPair<int, int>(i1, i2));
     }

     QFuture<void> future;
     future = QtConcurrent::map(intPairList, mapSumToQString);
     // future = QtConcurrent::map(intPairList.begin(), intPairList.end(), mapSumToQString);
}

问题:

运行此代码片段将生成SEGV 这里

代码语言:javascript
复制
namespace QtConcurrent {
// map kernel, works with both parallel-for and parallel-while
template <typename Iterator, typename MapFunctor>
class MapKernel : public IterateKernel<Iterator, void>
{
    MapFunctor map;
public:
    typedef void ReturnType;
    MapKernel(Iterator begin, Iterator end, MapFunctor _map)
        : IterateKernel<Iterator, void>(begin, end), map(_map)
    { }
    bool runIteration(Iterator it, int, void *) override
    {
        map(*it);                       <--------SEGV line
        return false;
    }

    //...
}

堆栈跟踪(从调试器复制)

代码语言:javascript
复制
1  QtConcurrent::MapKernel<QList<QPair<int, int>>::iterator, QtConcurrent::FunctionWrapper1<void, QPair<int, int>>>::runIteration  qtconcurrentmapkernel.h      68  0x404ee8   
2  QtConcurrent::MapKernel<QList<QPair<int, int>>::iterator, QtConcurrent::FunctionWrapper1<void, QPair<int, int>>>::runIterations qtconcurrentmapkernel.h      77  0x404f82   
3  QtConcurrent::IterateKernel<QList<QPair<int, int>>::iterator, void>::forThreadFunction                                          qtconcurrentiteratekernel.h  255 0x40466e   
4  QtConcurrent::IterateKernel<QList<QPair<int, int>>::iterator, void>::threadFunction                                             qtconcurrentiteratekernel.h  217 0x404486   
5  QtConcurrent::ThreadEngineBase::run                                                                                             qtconcurrentthreadengine.cpp 302 0x6d881973 
6  QThreadPoolThread::run                                                                                                          qthreadpool.cpp              99  0x111b36a  
7  QThreadPrivate::start(void *) *4                                                                                                qthread_win.cpp              403 0x11163eb  
8  KERNEL32!BaseThreadInitThunk                                                                                                                                     0x74d56359 
9  ntdll!RtlGetAppContainerNamedObjectPath                                                                                                                          0x77467c24 
10 ntdll!RtlGetAppContainerNamedObjectPath                                                                                                                          0x77467bf4 
11 ??

为了记录在案,还有另一个与此相关的https://stackoverflow.com/questions/52431737/qtconcurrentmap-segmentation-fault,但肯定没有提供可用的解决方案。

为什么我要得到这个SEGV,是什么导致了这个访问违规?

EN

回答 1

Stack Overflow用户

发布于 2020-06-01 07:24:09

老实说,你的一些问题对我来说还不清楚。然而,请考虑以下各点(尽管你可能已经考虑了其中的一部分或全部):

  1. 函子被强烈推荐为静态函数。从您的代码来看,您可能没有正确声明静态函数。请将以下内容放入您的MainWindow.h中:
代码语言:javascript
复制
static void mapSumToQString(QPair<int, int> pair);

并将实现修改如下:

代码语言:javascript
复制
// MapFunctor
void MainWindow::mapSumToQString(QPair<int, int> pair)
{
    j++;
    qDebug() << "Execute " << j << " = " << QString::number(pair.first, pair.second);;
}
  1. mapSumToQString是静态的,因此不能在其中使用MainWindow的非静态成员。因此,i也必须是静态的。
代码语言:javascript
复制
static int j; //in MainWindow.h ---> I changed i to j to make it differ from your For loop variable
int MainWindow::j = 0;//in MainWindow.cpp ----> static variables have to be initialized
  1. 修改MainWindow.cpp如下:
代码语言:javascript
复制
    // counter variable stored in MainWindow
    j = 0;

    QFuture<void> future;
    future = QtConcurrent::map(intPairList, mapSumToQString);
    future.waitForFinished();
  1. 我无法理解的一件事是,您正在将整数转换为带有随机基的字符串?!
代码语言:javascript
复制
qDebug() << "Execute " << j << " = " << QString::number(pair.first, pair.second);
//Herein, pair.second is random, and hence QString::number's second input (base) is always a random number. Do you really want it?
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62124748

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档