Qt5中的内存泄漏?如何删除QMimeData? [英] Memory leak in Qt5? How to get QMimeData deleted?

查看:357
本文介绍了Qt5中的内存泄漏?如何删除QMimeData?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是为这个问题提供了答案,并且当我注意到新创建的QListModel::mimeData()返回的>实例不会被删除.

I just provided an answer for this question and wanted to provide a working example when I noticed that newly created QMimeData instance returned by QListModel::mimeData() won't get deleted until the application gets terminated.

因此,这不是真正的内存泄漏,因为Qt在关闭时会处理所有QMimeData实例,但您只需要拖放足够长的时间,然后将正确的内容放入mime数据中,以便内存已满.

So this is not a real memory leak since Qt handles all QMimeData instances on shutdown but you only have to drag&drop long enough and put the right content into your mime data to let the memory run full.

我错过了什么吗?有没有办法告诉Qt一旦不再需要QMimeData实例,就删除它们?

Did I miss something? Is there a way to tell Qt to delete the QMimeData instances as soon as they are not needed any more?

请注意:

我知道Qt会在程序终止时自动删除QMimeData的每个实例. 我的问题不是valgrindcppcheck所报告的实际内存泄漏,但看起来多个QMimeData实例(可能非常大)在运行时没有清除,这也会消耗大量内存.

I know that every instance of QMimeData gets deleted by Qt automatically on program termination. My problem here is not a real memory leak as reported by valgrind or cppcheck but it looks like the multiple and potentially very large QMimeData instances get not cleaned up at runtime which blows up memory consumption as well.

示例代码:

#include <QtWidgets>
#include <iostream>

struct TrackedMimeData : public QMimeData {
   TrackedMimeData(const QString & text) {
      std::cout << this << std::endl;
      setText(text);
   }
   ~TrackedMimeData() {
       std::cout << "~" << this << std::endl;
   }
};

struct MyListWidget : QListWidget {
   MyListWidget() {
      setDragEnabled(true);
      addItem("item1");
      addItem("item2");
   }
   QMimeData * mimeData(const QList<QListWidgetItem *>) const override {
      return new TrackedMimeData("hello");
   }
};

int main(int argsc, char *argsv[]) {
   QApplication application(argsc, argsv);
   MyListWidget gui;
   gui.show();
   return application.exec();
}

示例输出如下:

0xa58750
0xa4e0f0
~0xa4e0f0
0xa3c6c0
~0xa3c6c0
0xa51880
0xa5ecd0
0xa31f50
0xa57db0
0xa5afc0
~0xa5afc0
0xa5aa70
~0xa5aa70
------ CLOSE WINDOW
~0xa58750
~0xa51880
~0xa5ecd0
~0xa31f50
~0xa57db0

只有在接受放置时,析构函数才会被调用 .

The destructors get called before closing the application only when the drop get's accepted.

顺便说一句.我在一台计算机上使用国产Qt 5.6 @ 1fcdb6cafcf -在另一台计算机上预编译的 5.6.0-19.fc23 Fedora 23上.因此,我怀疑这只是暂时的发展状态.

Btw. I'm on a home-grown Qt 5.6 @1fcdb6cafcf - on one computer and on 5.6.0-19.fc23 Fedora 23 precompiled on another. So I doubt it's just a temporary development state.

推荐答案

仅当您忘记删除mimeData()返回的指针时,才会发生内存泄漏.您必须像使用任何指针一样管理所有权.

There is a memory leak only if you forget to delete the pointer returned by mimeData(). You have to manage the ownership as with any pointer.

例如,如果使用setMimeData()mimeData()返回的指针传递给QDrag对象,则他将拥有该对象的所有权,并会在拖动操作结束时负责将其删除.在这种情况下,没有内存泄漏.

For instance, if you pass the mimeData() returned pointer to a QDrag object using setMimeData(), he will take ownership of it, and will take care of deleting it at the end of the drag operation. There is no memory leak in this case.

请参阅: http://doc.qt.io/qt-5/qdrag.html#setMimeData

这篇关于Qt5中的内存泄漏?如何删除QMimeData?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆