Header:
#ifndef CONTROLLER_THREAD
#define CONTROLLER_THREAD
#include <QThread>
#include <QTimer>
class Worker : public QObject
{
Q_OBJECT
public:
QTimer timer;
Worker();
~Worker();
private slots:
void calculateImage();
signals:
void imageReady();
};
class Controller: public QObject
{
Q_OBJECT
public:
QThread objQThread;
Controller();
~Controller();
public slots:
void receiveImage();
};
#endif // CONTROLLER_THREAD
Source:
#include <controller_thread.h>
#include <iostream>
using namespace std;
Worker::Worker()
{
connect( &timer, SIGNAL(timeout()), this, SLOT(calculateImage()) );
timer.start(1000);
}
Worker::~Worker() {}
void Worker::calculateImage()
{
}
Controller::Controller()
{
Worker *objWorker = new Worker();
objWorker->moveToThread( &objQThread );
connect( &objQThread, &QThread::finished, objWorker, &QObject::deleteLater );
connect( objWorker, &Worker::imageReady, this, &Controller::receiveImage );
objQThread.start();
}
Controller::~Controller()
{
objQThread.quit();
objQThread.wait();
}
void Controller::receiveImage()
{
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
#include "controller_thread.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Controller f;
MainWindow w;
w.show();
return a.exec();
}
MainWindow class is empty currently:
Header:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
};
#endif // MAINWINDOW_H
Source:
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
}
MainWindow::~MainWindow()
{
}
Valgrind says:
$ valgrind ./qmultithreading_paint
==17570== Memcheck, a memory error detector
==17570== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==17570== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==17570== Command: ./qmultithreading_paint
==17570==
QObject::killTimer: Timers cannot be stopped from another thread
QObject::~QObject: Timers cannot be stopped from another thread
==17570==
==17570== HEAP SUMMARY:
==17570== in use at exit: 1,333,179 bytes in 14,454 blocks
==17570== total heap usage: 106,397 allocs, 91,943 frees, 8,932,264 bytes allocated
==17570==
==17570== LEAK SUMMARY:
==17570== definitely lost: 156 bytes in 2 blocks
==17570== indirectly lost: 58 bytes in 1 blocks
==17570== possibly lost: 16,177 bytes in 217 blocks
==17570== still reachable: 1,234,172 bytes in 13,558 blocks
==17570== of which reachable via heuristic:
==17570== length64 : 5,336 bytes in 89 blocks
==17570== newarray : 2,160 bytes in 55 blocks
==17570== suppressed: 0 bytes in 0 blocks
==17570== Rerun with --leak-check=full to see details of leaked memory
==17570==
==17570== For counts of detected and suppressed errors, rerun with: -v
==17570== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$
What is valgrind talking about here? How can I fix it?
definitely lost: 156 bytes in 2 blocks ==17570== indirectly lost: 58 bytes in 1 blocks
The leak seems to be in the library (Qt) code and is largely inconsequential. If you really want to have a shot at fixing it, you must first get rid of the Timers cannot be stopped from another thread
error. See e.g. this answer.
I'm almost certain that the timer list leaks: see _q_reregisterTimers
handler - it's not called if the object is in the wrong thread, and thus the list isn't deleted.