【发布时间】:2011-08-10 14:39:05
【问题描述】:
我使用的是 Qt4.6,在 64 位 Linux 下编译的 32 位,并且有一个我无法弄清楚的令人费解的内存问题。我有一个包含 QLabel 的 QWidget。此 QLabel 用作每个重绘设置的绘画区域:
m_label->setPixmap(QPixmap::fromImage(image));
图像在小部件paintEvent中更新:
void MemTest::paintEvent(QPaintEvent* pEvent)
{
// Wait for latest painting if not finished, then perform threaded repaint
m_plotThread->wait();
m_plotThread->start();
}
也就是说,绘制是使用 QThread 线程执行的,其中线程函数如下所示:
void PlotThread::run()
{
// Lock the thread
m_mutex.lock();
// Image for painting
QImage image(400, 300, QImage::Format_ARGB32);
image.fill(0);
// Create painter on the image
QPainter painter(&image);
painter.setRenderHint(QPainter::Antialiasing, true);
QFont font("Helvetica", m_textSize);
painter.setFont(font);
painter.setPen(QColor(255,0,0));
painter.setBrush(QColor(130,150,255));
// Draw some shapes
painter.drawLine(0, 0, 400, 300);
painter.setPen(QColor(40,30,30));
painter.drawEllipse(15, 50, 130, 90);
// Draw the text
// !!! This causes memory leak !!!
painter.drawText(QPoint(40, 100), "What's my problem?");
m_mutex.unlock();
// Send painted image through signal
emit plotFinished(image);
}
一切都按预期工作,除了 drawText 导致严重的内存泄漏,在多次绘制后很容易检测到。该问题仅在绘制完成线程并使用 drawText 时出现。如果 drawText 被删除,或者如果它直接使用,而不是线程,在小部件paintEvent 中没有问题。例如使用drawLine、drawRect、drawEllipse等多线程绘制没有问题。
对这种行为有解释吗?而drawText函数如何多线程使用而不造成泄漏?
【问题讨论】:
-
您是如何检测到内存泄漏的?
-
我认为在 Qt 中不允许从非 GUI 线程进行绘画...
-
@Evan:确实有限制,但在大多数情况下是允许的(见答案)
-
@Bart:我还没有真正使用任何工具来跟踪泄漏。我只是在 Fedora 中使用系统监视器看到它,因为它是一个非常严重的泄漏......
-
你可以使用 valgrind 来检测内存泄漏。我对 drawText() 也有同样的问题,valgrind 报告了很多泄漏... :(
标签: c++ multithreading qt memory-leaks