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

Multithread signal/slot memory leak in ubuntu

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Invalid
    • Icon: P3: Somewhat important P3: Somewhat important
    • None
    • 5.5.1
    • None
    • ubuntu 14.04LTS

      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
      

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

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

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes