如何通过Valgrind找到QThreads程序中的内存泄漏位置?

时间:2018-06-11 06:36:35

标签: c++ qt memory-leaks valgrind qthread

标题:

#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说:

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

标题

valgrind在这里谈论什么?我该如何解决?

  

绝对丢失:2个块中有156个字节       == 17570 ==间接丢失:1个块中58个字节

1 个答案:

答案 0 :(得分:1)

泄漏似乎是在库(Qt)代码中,并且在很大程度上是无关紧要的。如果你真的想要修复它,你必须首先摆脱Timers cannot be stopped from another thread错误。参见例如this answer

我几乎可以确定计时器列表是否泄漏:请参阅_q_reregisterTimers handler - 如果对象位于错误的线程中,则不会调用它,因此列表不会被删除。