Подтвердить что ты не робот

Как сделать приложения Qt GUI на С++ без утечек памяти

Мне не удалось создать приложение Qt GUI, в котором не было более 1 тыс. байтов с определенными потерями в valgrind. Я экспериментировал с этим, создавая минимальные приложения, которые показывают только один QWidget, расширяющий QMainWindow; которые просто создают объект QApplication, не показывая его или не выполняя его или оба, но они всегда течет.

Пытаясь понять это, я прочитал, что это потому, что у X11 или glibc есть ошибки, или потому что valgrind дает ложные срабатывания. И в одной теме форума, казалось, подразумевалось, что создание объекта QApplication в основной функции и возврат объекта exec() - функция, как это делается в учебниках, - это "упрощенный" способ создания GUI (и не обязательно хороших, возможно?).

Выход valgrind действительно упоминает libX11 и libglibc, а также libfontconfig. Остальные потери памяти, 5 записей потерь, происходят при ??? in libQtCore.so во время QLibrary::setFileNameAndVersion.

Если существует более подходящий способ создания приложений с графическим интерфейсом, который предотвращает даже некоторые из этих событий, что это такое? И если какой-либо выход valgrind является просто шумом, как создать файл подавления, который подавляет правильные вещи?

EDIT: Спасибо за комментарии и ответы!
Я не беспокоюсь о немногих потерянных kB, но легче будет найти свои собственные утечки памяти, если мне не придется фильтровать несколько экранов ошибок, но обычно можно получить "OK" от valgrind. И если я собираюсь подавить предупреждения, я лучше знаю, что это такое, верно?
Интересно видеть, насколько приемлемыми могут быть утечки!

4b9b3361

Ответ 1

Для широкомасштабных многопоточных библиотек, таких как QT, wxWidgets, X11 и т.д., нередко настраиваются объекты одноэлементного типа, которые инициализируются один раз при запуске процесса, а затем не предпринимают попыток очистите выделение при завершении процесса.

Я могу заверить вас, что все, что "просочилось" из функции, такой как QLibrary::setFileNameAndVersion(), было умышленно оставлено. Биты памяти, оставленные X11/glibc/fontConfig, вероятно, также не являются ошибками.

Это можно рассматривать как неправильную практику кодирования или этикет, но она также может значительно упростить определенные типы задач. Операционные системы в эти дни предлагают очень сильную гарантию на очистку любой памяти или ресурсов, оставшихся открытыми процессом, когда его убивают (изящно или силой), и если соответствующее распределение, скорее всего, потребуется на весь срок действия приложения, включая процедуры выключения - и различные ключевые компоненты QT будут квалифицироваться, - тогда это может быть благом для производительности, чтобы библиотека установила некоторые распределения памяти, как только она будет загружена/инициализирована, и позволит тем, чтобы они сохранялись бесконечно. Помимо всего прочего, это позволяет памяти присутствовать для использования другими деструкторами С++, которые могут ссылаться на эту память.

Поскольку эти распределения устанавливаются только один раз, и из одной точки кода нет риска значимой утечки памяти. Его просто память, которая принадлежит процессу и, таким образом, очищается, когда процесс закрывается операционной системой.

Заключение: если утечка памяти отсутствует в вашем коде, и со временем она становится значительно больше (и значительным в наши дни, думаю, мегабайты) и/или явно оканчивается от первоначальной инициализации который всегда вызывается только в вашем приложении, тогда не беспокойтесь об этом. Возможно, это намеренно.

Ответ 2

Один из способов проверить это может заключаться в том, чтобы запустить код внутри цикла и изменить количество итераций. Если разница между allocs и frees не зависит от количества итераций, вы, вероятно, будете в безопасности.