我是否需要明确删除顶级窗口以避免Qt中的内存泄漏?

时间:2014-04-08 14:19:47

标签: qt memory-management

在Qt中,父类被分配用于构造QObject。将parent设置为0会构造一个没有父对象的对象。如果对象是窗口小部件,它将成为顶级窗口。如果我在堆上创建顶级窗口,是否需要显式删除顶级窗口以避免内存泄漏?或者Qt会照顾它。如果是这样,Qt什么时候删除它?关闭小部件或关闭应用程序?

4 个答案:

答案 0 :(得分:3)

据我了解,现有的答案都是错误的。

https://qt.gitorious.org/qt/qtbase/source/f02e1d6d8e0ee560667b445e8fa43bde85e31f41:src/widgets/kernel/qapplication.cpp#L770

销毁QApplication时,顶级窗口小部件全部被删除。

在顶级窗口关闭之前,QApplication确实不会从事件循环返回,但这与问题无关。

只要您的QApplication被正确销毁(即在堆栈上创建或以其他方式删除),所有小部件都将被删除。

您不必删除顶级窗口小部件,不这样做不会导致技术上或其他方面的泄漏。

(这是顶级QObject的情况,只有QWidgets,由QApplication跟踪)

答案 1 :(得分:2)

Technically

  

内存泄漏是指通过运行代码但仍然存储在内存

中无法访问对象的情况

简短的回答是。使用

随时随地you can access your top level widgets
QWidgetList QApplication::topLevelWidgets();

即使堆上的顶级窗口小部件没有父窗口,它们也与QApplication对象关联。而且这个对象的生命周期恰好是程序的生命周期。因此,即使QApplication对象没有删除顶级窗口小部件,当他被删除时,您的进程也会被终止。这意味着这些小部件很快就会被删除。

存在泄漏,但它发生在您从main()返回到您的流程成为僵尸的时间之间。这完全没问题。

不释放顶级小部件的最大缺点是使用内存分析器会出现误报。

答案 2 :(得分:2)

对于QWidget,您可以设置Qt :: WA_DeleteOnClose属性,以便在关闭QWidget时,将调用其析构函数。这将反过来调用所有子窗口小部件的析构函数,确保任何内存分析器都不会显示误报。

答案 3 :(得分:1)

不,你必须自己处理顶级小部件。如果您创建具有2个或更多窗口小部件而没有父窗口的应用程序,您可能会注意到,当您关闭主窗口时,其他窗口仍然处于活动状态并继续运行,除非您在主窗口小部件closeEvent()中选择了不同的行为。

如果您要关闭并删除所有其他热门小部件,您可以在主要小部件的closeEventhide()所有其他热门窗口中使用deleteLater()或直接删除它们< / p>