Как найти, где утечка памяти в программе QThreads через Valgrind? - PullRequest
0 голосов
/ 11 июня 2018

Заголовок:

#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

Источник:

#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 в настоящее время пуст:

Заголовок:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
};

#endif // MAINWINDOW_H

Источник:

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
}

MainWindow::~MainWindow()
{    
}

Вальгринд говорит:

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

Заголовок

О чем здесь говорит Валгринд?Как я могу это исправить?

определенно потеряно: 156 байтов в 2 блоках == 17570 == потеряно косвенно: 58 байтов в 1 блоках

1 Ответ

0 голосов
/ 11 июня 2018

Утечка, кажется, происходит в коде библиотеки (Qt) и в значительной степени несущественна.Если вы действительно хотите попытаться это исправить, сначала вы должны избавиться от ошибки Timers cannot be stopped from another thread.См., Например, этот ответ .

Я почти уверен, что утечка списка таймеров: см. _q_reregisterTimers обработчик - он не вызывается, если объект находится в неправильномпоток, и, следовательно, список не удаляется.

...