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

QTextDocument: suffers from memory leak in drawContents() when there is no layout set on the document

    XMLWordPrintable

Details

    • Bug
    • Resolution: Duplicate
    • Not Evaluated
    • None
    • 4.6.2
    • GUI: Text handling
    • None

    Description

      To reproduce the problem, use the following code:-

      #include <QtGui> 
      #include <QtDebug> 
      
      class PrintThread : public QThread 
      { 
      public: 
      PrintThread(QObject* parent) 
      : QThread(parent) 
      { 
      } 
      
      void run() 
      { 
      /*forever 
      { 
      QImage image(128, 128, QImage::Format_ARGB32_Premultiplied); 
      image.fill(0x0); 
      QPainter p(&image); 
      QTextDocument document; 
      document.setPlainText(QLatin1String("render this string")); 
      document.drawContents(&p); 
      }*/ 
      qDebug()<<"thread start"; 
      QImage image(128, 128, QImage::Format_ARGB32); 
      image.fill(0x0); 
      QPainter p(&image); 
      QTextDocument document; 
      document.setPlainText(QLatin1String("render this string")); 
      document.drawContents(&p); 
      qDebug()<<"thread finished"; 
      } 
      }; 
      
      class MyWidget : public QWidget 
      { 
      Q_OBJECT 
      public: 
      MyWidget(); 
      private slots: 
      void slotStart(); 
      void deleteThreadLater(); 
      void start10Thread(); 
      private: 
      QLineEdit *m_edit; 
      QPushButton *m_print; 
      PrintThread* m_thread; 
      QTimer m_timer; 
      }; 
      
      MyWidget::MyWidget() 
      :m_thread(NULL) 
      { 
      QVBoxLayout* mainLayout = new QVBoxLayout(this); 
      m_print = new QPushButton("Start Timer"); 
      connect(m_print, SIGNAL(clicked()), this, SLOT(start10Thread())); 
      connect(&m_timer, SIGNAL(timeout()), this, SLOT(slotStart())); 
      m_edit = new QLineEdit; 
      mainLayout->addWidget(m_print); 
      mainLayout->addWidget(m_edit); 
      } 
      void MyWidget::slotStart() 
      { 
      if(NULL == m_thread) 
      { 
      m_thread = new PrintThread(this); 
      connect(m_thread, SIGNAL(finished()), this, SLOT(deleteThreadLater())); 
      m_edit->setText("new thread starting"); 
      m_thread->start(); 
      } 
      } 
      void MyWidget::start10Thread() 
      { 
      if(!m_timer.isActive()) 
      { 
      m_timer.start(2000); 
      m_print->setText("Stop Timer"); 
      } 
      else 
      { 
      m_timer.stop(); 
      m_print->setText("Start Timer"); 
      } 
      } 
      void MyWidget::deleteThreadLater() 
      { 
      if(NULL != m_thread) 
      { 
      delete m_thread; 
      m_thread = NULL; 
      m_edit->setText("thread stopped"); 
      } 
      } 
      
      int main(int argc, char *argv[]) 
      { 
      QApplication app(argc, argv); 
      MyWidget* widget = new MyWidget(); 
      widget->show(); 
      return app.exec(); 
      } 
      
      #include "main.moc"
      

      As a workaround you can do the following:-

      qDebug()<<"thread start"; 
      		QImage image(128, 128, QImage::Format_ARGB32);
      		QPainter p(&image);
      		image.fill(0x0);
      		QTextDocument document; 
      		QPlainTextDocumentLayout *layout = new     QPlainTextDocumentLayout(&document);
      		document.setDocumentLayout(layout);
      		document.setPlainText(QLatin1String("render this string"));
      		document.drawContents(&p); 
      		delete layout;
      		qDebug()<<"thread finished"; 
      

      qtextdocument.cpp has the following method call if no layout has been set, a new text document is created which doesn't appear to be deleted:-

      QAbstractTextDocumentLayout *QTextDocument::documentLayout() const
      {
          Q_D(const QTextDocument);
          if (!d->lout) {
              QTextDocument *that = const_cast<QTextDocument *>(this);
              that->d_func()->setLayout(new QTextDocumentLayout(that));
          }
          return d->lout;
      }
      

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              esabraha Eskil Abrahamsen Blomfeldt
              cattell Matthew Cattell (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes