【问题标题】:Do I need to explicitly delete top level windows to avoid memory leakage in Qt?我是否需要显式删除顶级窗口以避免 Qt 中的内存泄漏?
【发布时间】:2014-04-08 14:19:46
【问题描述】:

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

【问题讨论】:

    标签: qt memory-management


    【解决方案1】:

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

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

    当 QApplication 被销毁时,顶层小部件全部被删除。

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

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

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

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

    【讨论】:

      【解决方案2】:

      Technically

      内存泄漏是指运行代码无法访问对象但仍存储在内存中

      简短的回答是。事情是you can access your top level widgets随时随地使用

      QWidgetList QApplication::topLevelWidgets();
      

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

      有一个泄漏,但它发生在您从main() 返回到您的进程变成僵尸的时间之间。这完全没问题。

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

      【讨论】:

      • 你的意思是关闭应用后没有内存泄漏?
      • 操作系统总能恢复他的记忆。内存泄漏的问题是你正在运行并且虚拟地持有在你死之前无法释放的资源,甚至你也无法使用它们。
      • 但是 QApplication 对象确实删除了顶级小部件,请参阅我的回答。
      • @OliJG Do I need to explicitly delete top level windows to avoid memory leakage 我告诉 OP:只要应用程序对象存在,顶级小部件就没有内存泄漏。他是否删除它们无关紧要。
      • “有一个泄漏,但它发生在你从 main() 返回的时间和你的进程变成僵尸的时间之间。” - 事实并非如此。没有泄漏,因为它们已被删除。使用内存分析器不会出现误报。
      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        如果你想关闭并删除所有其他顶部小部件,你可以在主小部件的closeEvent中进行(hide()所有其他顶部窗口并使用deleteLater()或直接删除它们)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-11-30
          • 1970-01-01
          • 1970-01-01
          • 2022-08-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多