Я только что предоставил ответ на этот вопрос и хотел предоставить рабочий пример, когда заметил, что вновь созданный экземпляр QMimeData
возвращается QListModel::mimeData()
не будет удален, пока приложение не будет завершено.
Таким образом, это не настоящая утечка памяти, поскольку Qt обрабатывает все экземпляры QMimeData
при выключении, но вам нужно только перетаскивать и вставлять нужное содержимое в ваши MIME-данные, чтобы память заполнялась.
Я что-то пропустил? Есть ли способ сказать Qt удалить экземпляры QMimeData
, как только они больше не нужны?
Обратите внимание:
Я знаю, что каждый экземпляр QMimeData
автоматически удаляется Qt при завершении программы. Моя проблема здесь не в настоящей утечке памяти, о которой сообщают valgrind
или cppcheck
, но похоже, что множественные и потенциально очень большие экземпляры QMimeData
не очищаются во время выполнения, что также увеличивает потребление памяти.
Пример кода:
#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
Деструкторы вызываются перед закрытием приложения только после принятия удаления.
Кстати. Я использую доморощенный Qt 5.6 @1fcdb6cafcf — на одном компьютере и на 5.6.0-19.fc23 Fedora 23, предварительно скомпилированном на другом. Так что я сомневаюсь, что это просто временное состояние развития.
QMimeData
наследуетQObject
и хранит свои данные внутри какQVector
строк иQVariant
пар. У него такие же ограничения на управление памятью, как и у любого другого класса, производного отQObject
. - person anonymous   schedule 16.06.2016cppcheck
ничего не найдет в этом примере, потому что экземплярQMimeData
в конце удаляется. Но до тех пор я мог бы хранить гигабайты данных в тысячах экземпляров новыхQMimeData
экземпляров, что, я признаю, не является классической утечкой памяти. - person frans   schedule 16.06.2016QMimeData
илиQDrag
, чтобы знать, когда операция перетаскивания прерывается. В настоящее время я не могу узнать, например. когда скрыть некоторые виджеты по требованию. - person frans   schedule 16.06.2016QMimeData
соответствующему обработчику. Это похоже на случай потенциальной утечки, если вновь созданный объектQMimeData
не получает родителя от создавшего его объекта (или если вы не удаляете его напрямую). - person anonymous   schedule 17.06.2016