如何通过Valgrind找到QThreads程序中的内存泄漏在哪里?

How to find where is memory leak in QThreads program through Valgrind?

本文关键字:内存 泄漏 在哪里 程序 何通过 Valgrind 找到 QThreads      更新时间:2023-10-16

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

源:

#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()
{
}

主.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== 间接丢失:1 个块中 58 个字节

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

我几乎可以肯定计时器列表泄漏:请参阅_q_reregisterTimers处理程序 - 如果对象在错误的线程中,则不会调用它,因此列表不会被删除。