2017-04-03 114 views
0

我使用QP 5.7作为QProgressBar的GUI应用程序。我怀疑可能会有内存泄漏,因为内存使用量在运行时增加了大约50MB/s。我可以将问题缩小为一行代码。QProgressBar :: setValue(int)导致内存泄漏?

QProgressBar *pbarQuality; 
... 
int curQuality = data.getQuality(); 
if (curQuality < 0) { 
    curQuality = 0; 
    qWarning("Value set to 0. "); 
} 
if (curQuality > 100) { 
    curQuality = 100; 
    qWarning("Value set to 100. "); 
} 
ui.pbarQuality->setValue(curQuality); //The memory problem doesn't occur when this single line is commented out 

QProgressBar(pbarQuality)的值仅用于显示。它不在别的地方使用。

我觉得这是一个非常奇怪的行为。我错过了什么吗?

下面是自动生成的代码由Qt设计:

 pbarQuality = new QProgressBar(frame_5); 
     pbarQuality->setObjectName(QStringLiteral("pbarQuality")); 
     pbarQuality->setGeometry(QRect(10, 50, 130, 23)); 
     pbarQuality->setValue(24); 
+0

向我们展示如何获得那个'* pbarquality'指针的值 – SingerOfTheFall

+0

使用valgrind来验证Qt是否有错误,而不是您的代码。它会告诉你确切的泄漏来自哪里。 –

+0

@SingerOfTheFall我从来没有设置或得到它。我使用Qt Designer来创建GUI。 – dcfyg

回答

0

我的应用程序除了定期(最多每秒60次)向GUI线程发送信息(图像)的GUI线程外,还运行另一个线程。我正在GUI线程中做一些小的图像编辑(调整大小)。事实证明,这需要很长的时间才能跟上另一个线程发布的数据。因此事件队列变得越来越大,所使用的RAM也变得越来越大。

获得的经验:如果定期发布数据,请注意线程的处理速度。数据处理需要在新数据可用之前完成。

感谢@KubaOber给我提示。

+0

只是想知道你是怎么想出来的 – chbchb55

+1

@ chbchb55我正在寻找导致所谓内存泄漏的代码行。在逐步执行应用程序时,我在每个步骤后都采用了内存快照(在Visual Studio中),以确定内存中的点增加了。我注释了不同的代码行,直到泄漏不再发生(这是当我怀疑QProgressBar():: setValue()是问题时。当我注意到累计的RAM数量大约是图像的大小并且我读到发出的事件排队等待处理,直到问题出现为止。 – dcfyg

1

尝试通过pbarQuality.update(); QCoreApplication::processEvents();更换setValue,看看是否能重现问题。如果是这样,你可以利用嵌套的事件循环来保持图形用户界面的响应,同时阻塞代码运行,这是一件坏事。 setValue呼叫processEvents作为一种天真的方式来处理破碎的用户代码。恕我直言,这是一个危险的好处。唯一的解决方法就是解开代码并将控制返回到主事件循环而不是阻塞。

This answer显示了如何通过利用QImage的RAII行为来避免图像风暴的影响,并链接到另一个通过利用OpenGL演示自由图像缩放的答案。