Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-49679

Multithread signal/slot memory leak in ubuntu

    XMLWordPrintable

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
      

      Attachments

        1. main.cpp
          0.2 kB
          tomhk215
        2. mainwindow.cpp
          1 kB
          tomhk215
        3. mainwindow.h
          0.5 kB
          tomhk215
        4. mainwindow.ui
          1 kB
          tomhk215
        5. myobject.cpp
          0.7 kB
          tomhk215
        6. myobject.h
          0.4 kB
          tomhk215
        7. mythread.cpp
          0.3 kB
          tomhk215
        8. mythread.h
          0.2 kB
          tomhk215
        9. QThreadMemoryLeak.pro
          0.4 kB
          tomhk215
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            thiago Thiago Macieira
            tomhk215 tomhk215
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes