无法检测为什么QDialog是内存泄漏

时间:2013-03-28 04:41:55

标签: qt memory-leaks qdialog application-verifier

我正在使用Qt进行一个项目,其中包含一些用于用户输入的自定义QDialog。由于我的开发盒的硬件限制,我想监视我的应用程序的内存使用情况。我如何执行对话。

1 void MainWindow::callDialog() {
2     DlgPopConfig dialog(&theApp->cfgPop, m_fnPopCfg, this);
3     dialog.exec();
4     m_fnPopCfg = dialog.fileName();
5     lbl_fnPopCfg->setText(m_fnPopCfg);
6 }

由于对话框是局部变量,我希望它在堆栈上创建并在函数结束后立即销毁(在第5行之后)。当应用程序重复打开和关闭对话框时,其内存使用率会上升,并且永远不会返回到任务管理器的初始值['Memory (Working Set)' and 'Memory (Private Working Set)'列]。我使用了 Application Verifier ,启用了所有基本测试,并且没有显示错误'。内存模式如下所示(数值仅由插图组成):

  • 申请开始(工作集= 12000K,私人集= 6000K)
  • 打开Dialog-1(工作集= 14000K,私有集= 7000K)
  • 关闭对话框(工作集= 12010K,私人集= 6005K)
  • 打开Dialog-2(工作集= 14020K,私人集= 7000K)
  • 关闭对话框(工作集= 12010K,私有集= 6008K)
  • 打开Dialog-3(工作集= 14080K,私人集= 7010K)
  • 关闭对话框(工作集= 12040K,私有集= 6008K)
  • ...

那么,有什么想法来追查问题的根本原因? (实际上,当使用QFileDialog getOpenFileName getSaveFileName的静态方法时,我也遇到了类似的问题,并且发现了一些讨论here,但似乎没有解决)

编辑我在对话框中使用了QFormLayout,并且我按layout->addRow("label text", mywidget);添加了小部件,我怀疑对象破坏是否无法干净地删除标签。

编辑我创建了一个测试程序,QDialog有十个QLineEdits,使用相同的add-widget策略。问题依然存在。 (如果我经常创建并关闭对话框,那么这个测试程序就会出现问题,一秒钟说10次)

mainwindow.h

#include <QMainWindow>
#include <QPushButton>
#include <QDialog>
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
private:
    QPushButton * button;
private slots:
    void button_click();
};
class Dialog : public QDialog
{
    Q_OBJECT
public:
    explicit Dialog(QWidget *parent = 0);
};

mainwindow.cpp

#include "mainwindow.h"
#include <QApplication>
#include <QFormLayout>
#include <QLineEdit>
#include <QLabel>

MainWindow::MainWindow(QWidget *parent):QMainWindow(parent)
{
    button=new QPushButton(this);setCentralWidget(button);
    connect(button,SIGNAL(clicked()),SLOT(button_click()));
}
void MainWindow::button_click()
{
    Dialog d(this);
    d.exec();
}
Dialog::Dialog(QWidget *parent):QDialog(parent)
{
   QFormLayout*layout=new QFormLayout(this);
   setLayout(layout);
   for (int i = 0; i < 10; i++)
   {
       layout->addRow(QString("%1").arg(i+1), new QLineEdit(this));
   }
}
int main(int c,char *argv[])
{
    QApplication a(c,argv);
    MainWindow w;
    w.show();
    return a.exec();
}

平台

  • Win 7 x64,MinGW 4.7.2 x64(rubenvb-build),4GB ram
  • Qt 4.8.5(使用上述工具链本地构建)
  • Qt-Creator 2.6.1(使用上述工具链本地构建)

1 个答案:

答案 0 :(得分:2)

迟了几个月,但这可能会帮助遇到这个问题的下一个人。我正在使用PySide,但内存泄漏相同。结果是两个选项,具体取决于您从对话框中返回所需的信息:

1)完成删除对话框以便删除。

在Python中,这看起来像:

dialog = MyDialog(self)
dialog.exec_()
# Do other things with dialog
dialog.deleteLater()

它在你的C ++代码中看起来应该类似:

void MainWindow::button_click()
{
    Dialog d(this);
    d.exec();
    // Do other things with d
    d.deleteLater()
}

2)设置WA_DeleteOnClose属性。

我最终在自定义对话框的构造函数中包含了这个:

    self.setAttribute(PySide.QtCore.Qt.WA_DeleteOnClose)

在C ++代码中应该看起来像这样:

Dialog::Dialog(QWidget *parent):QDialog(parent)
{
   QFormLayout*layout=new QFormLayout(this);
   setLayout(layout);
   setAttribute(Qt::WA_DeleteOnClose);
   for (int i = 0; i < 10; i++)
   {
       layout->addRow(QString("%1").arg(i+1), new QLineEdit(this));
   }
}

这两个都为我修复了内存泄漏,但是如果我连续多次打开/关闭对话框,它偶尔会泄漏4kb。对于以Python为中心的答案感到抱歉 - 希望这可以指出人们正确的方向。