0

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)
$

Heading

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

Aquarius_Girl
  • 21,790
  • 65
  • 230
  • 411
  • compile your code with -ggdb3 flag and then use valgrind, you will get exact line that is giving memory leaks. – HarshGiri Jun 11 '18 at 06:50
  • And run Valgrind with --leak-check=full as it tells you to do. – Paul Floyd Jun 11 '18 at 08:22
  • 1
    Please minimize the problem to get rid of everything that's irrelevant. For example, do you need the main window to reproduce the problem? If not, remove it. Do you need any of the empty methods? Etiquette demands that you get rid of noise from the question: anything not needed should be removed. That's what minimization is. You'll also notice that the question gets even shorter when everything is in a single file: SO questions aren't Java enterprise projects. You don't need header files nor one-class-per-file etc. Boilerplate detracts from the meat of the question! – Kuba hasn't forgotten Monica Jun 11 '18 at 13:13
  • @KubaOber thanks for the reminder. Will try to be careful in future. – Aquarius_Girl Jun 12 '18 at 04:16

1 Answers1

1

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.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313