Details
-
Bug
-
Resolution: Invalid
-
P3: Somewhat important
-
None
-
5.5.1
-
None
-
ubuntu 14.04LTS
Description
Memory leak after emitting queued signal with a constant reference parameter form a qobject from another thread.
This is my post at stackoverflow: http://stackoverflow.com/questions/33956972/memory-leak-in-qt-emitting-const-container
typedef QList<long double> doubleList; class MyThread : public QThread { public: MyThread(); ~MyThread(); }; class MyObject : public QObject { Q_OBJECT public: explicit MyObject(QObject *parent = 0); ~MyObject(); signals: void jobDone(const doubleList&); public slots: void jobStart(); }; namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; private slots: void buttonClicked(); void receiveResult(const doubleList&); };
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); qDebug() << "GUI Thread ID: " << QThread::currentThreadId(); connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::buttonClicked); qRegisterMetaType<doubleList>("doubleList"); } MainWindow::~MainWindow() { delete ui; } void MainWindow::buttonClicked() { MyThread* thread = new MyThread; MyObject* object = new MyObject; object->moveToThread(thread); connect(thread, &MyThread::started, object, &MyObject::jobStart); connect(object, &MyObject::jobDone, this, &MainWindow::receiveResult); connect(object, &MyObject::jobDone, thread, &MyThread::quit); connect(thread, &MyThread::finished, object, &MyObject::deleteLater); connect(thread, &MyThread::finished, thread, &MyThread::deleteLater); thread->start(); } void MainWindow::receiveResult(const doubleList &) { qDebug() << "Received result"; } MyThread::MyThread() { qDebug() << "MyThread ctor, thread ID:\t" << currentThreadId(); } MyThread::~MyThread() { qDebug() << "MyThread dtor, thread ID:\t" << currentThreadId(); } MyObject::MyObject(QObject *parent) : QObject(parent) { qDebug() << "MyObject ctor. MyObject pointer:\t" << this << "\tThread ID:\t" << QThread::currentThreadId(); qRegisterMetaType<doubleList>("doubleList"); } MyObject::~MyObject() { qDebug() << "MyObject dtor and list deleted. MyObject pointer:\t" << this << "\tThread ID:\t" << QThread::currentThreadId(); } void MyObject::jobStart() { doubleList list; qDebug() << this << "jobStart() called. Thread ID:\t" << QThread::currentThreadId(); for (int i = 0; i != 100000000; ++i) { list.push_back(i); } emit jobDone(list); } int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
MyThread ctor, thread ID: 0x7f3dbbbf1780 MyObject ctor. MyObject pointer: MyObject(0xbc03a0) Thread ID: 0x7f3dbbbf1780 MyObject(0xbc03a0) jobStart() called. Thread ID: 0x7f3d9e6df700 Received result MyObject dtor and list deleted. MyObject pointer: MyObject(0xbc03a0) Thread ID: 0x7f3d9e6df700 MyThread dtor, thread ID: 0x7f3dbbbf1780 MyThread ctor, thread ID: 0x7f3dbbbf1780 MyObject ctor. MyObject pointer: MyObject(0xbafca0) Thread ID: 0x7f3dbbbf1780 MyObject(0xbafca0) jobStart() called. Thread ID: 0x7f3d9e6df700 Received result MyObject dtor and list deleted. MyObject pointer: MyObject(0xbafca0) Thread ID: 0x7f3d9e6df700 MyThread dtor, thread ID: 0x7f3dbbbf1780 MyThread ctor, thread ID: 0x7f3dbbbf1780 MyObject ctor. MyObject pointer: MyObject(0xbc03a0) Thread ID: 0x7f3dbbbf1780 MyObject(0xbc03a0) jobStart() called. Thread ID: 0x7f3d9e6df700 Received result MyObject dtor and list deleted. MyObject pointer: MyObject(0xbc03a0) Thread ID: 0x7f3d9e6df700 MyThread dtor, thread ID: 0x7f3dbbbf1780