Memory leak in Qt5? How to get QMimeData deleted?

前端 未结 2 751
难免孤独
难免孤独 2021-01-18 15:52

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 QList

相关标签:
2条回答
  • 2021-01-18 15:55

    It should be happening, if it isn't, then it's a bug - there's nothing you can do about it, other than reporting it if it hasn't been reported yet.

    I can't reproduce it on OS X with Qt 5.6. It may be platform-specific, or an already fixed bug in an old Qt version. As soon as I release the mouse button at the end of the drag, the mime data gets deleted. The call stack when the destructor executes has the QDrag destructor called from the event loop via deleteLater somewhere. I've used your code verbatim.

    Sidebar: It could be made just a bit more minimal, if you really wanted it as short as possible. Here's what I got, although I agree it's mostly splitting hair. Your question beats 99% other questions by providing a working example - big kudos for that! The things that I think matter for brevity are:

    1. Inclusion of the entire needed Qt module(s).
    2. Use of qDebug instead of std::cout & al, it saves an include and is more Qt style.
    3. Access specifiers don't matter if you use struct anyway.
    4. Generally speaking, destructors are either virtual in the public base class, or they can never be without succumbing to slicing. So you don't have to spell that out.

    I have example code where I don't follow this, of course. I like to call it legacy code :)

    #include <QtWidgets>
    
    struct TrackedMimeData : QMimeData {
       TrackedMimeData(const QString & text) {
          qDebug() << this;
          setText(text);
       }
       ~TrackedMimeData() {
          qDebug() << "~" << this;
       }
    };
    
    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();
    }
    
    0 讨论(0)
  • 2021-01-18 16:08

    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.

    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.

    See : http://doc.qt.io/qt-5/qdrag.html#setMimeData

    0 讨论(0)
提交回复
热议问题