![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() |
Гость_Гость_* |
![]()
Сообщение
#1
|
Гости ![]() |
Есть базовый виджет
Уничтожается так:
От него наследуется другой виджет:
При нажатии на кнопку вызывается слот SlotDestroy, который вызывает деструктор:
При каждом цикле создания и удаления frmServiceSelect программа память освобождается не полностью. то 10-12 кб прибавляется к объему потребляемой оперативки, то 60-80... Как корректно подчистить память? |
|
|
![]() |
BRE |
![]()
Сообщение
#2
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
kwisp |
![]()
Сообщение
#3
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
а почему ты в диструкторе уничтожаешь объекты?
у тебя что webView, serviceButtons, _btnOk, _btnBack, _btnCancel не имеют parent`a ? |
|
|
Гость_Гость_* |
![]()
Сообщение
#4
|
Гости ![]() |
Паренты имеются, конечно же. А уничтожаю я так, для надежности
![]() |
|
|
Гость_Гость_* |
![]()
Сообщение
#5
|
Гости ![]() |
Скачал Deleaker - буду искать утечки
|
|
|
kwisp |
![]()
Сообщение
#6
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Паренты имеются, конечно же. А уничтожаю я так, для надежности я бы для надежности тогда уже писал
чтоб наверняка грохнуть! ![]() дока. Цитата Member Function Documentation Q_INVOKABLE QObject::QObject ( QObject * parent = 0 ) Constructs an object with parent object parent. The parent of an object may be viewed as the object's owner. For instance, a dialog box is the parent of the OK and Cancel buttons it contains. The destructor of a parent object destroys all child objects. Setting parent to 0 constructs an object with no parent. If the object is a widget, it will become a top-level window. See also parent(), findChild(), and findChildren(). |
|
|
Гость_Гость_* |
![]()
Сообщение
#7
|
Гости ![]() |
|
|
|
SABROG |
![]()
Сообщение
#8
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1207 Регистрация: 8.12.2008 Из: Russia, Moscow Пользователь №: 446 Спасибо сказали: 229 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
kwisp |
![]()
Сообщение
#9
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Цитата(kwisp @ 24.9.2009, 10:42) * delete webView; delete webView; Так надежности как раз не будет, так как программа просто упадет ![]() это же шутка была!. конечно упадет(в лучшем случае) а может и просто бед натворить по уничтожению других объектов. а второй твой вариант тоже не зачем:) |
|
|
BRE |
![]()
Сообщение
#10
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
kwisp |
![]()
Сообщение
#11
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
Litkevich Yuriy |
![]()
Сообщение
#12
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
kwisp |
![]()
Сообщение
#13
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
![]() |
|
|
igor_bogomolov |
![]()
Сообщение
#14
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
Всегда считал, что удалять классы потомки от QObject через delete чревато. Только через QObject::deleteLater(). Ведь к объекту может обратиться event loop, а мы уже класс грохнули. Получим крах приложения. Поправьте, если я не прав.
|
|
|
BRE |
![]()
Сообщение
#15
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
Всегда считал, что удалять классы потомки от QObject через delete чревато. Только через QObject::deleteLater(). Вовсе не чревато. Одновременно доступ к объекту может осуществляться только из разных потоков. Если этого нет, то любой объект можно спокойно удалять delete (даже если у него есть parent). Ведь к объекту может обратиться event loop, а мы уже класс грохнули. Получим крах приложения. Поправьте, если я не прав. Если сейчас выполняется твоя функция (в которой удаляется какой то объект), то это говорит о том, что процессор выполняет код этой функции, а не обрабатывает события или делает что-то еще. ![]() |
|
|
Litkevich Yuriy |
![]()
Сообщение
#16
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
BRE |
![]()
Сообщение
#17
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
Litkevich Yuriy |
![]()
Сообщение
#18
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
Сейчас глянул код деструктора - он давольно навороченый:
|
|
|
SABROG |
![]()
Сообщение
#19
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1207 Регистрация: 8.12.2008 Из: Russia, Moscow Пользователь №: 446 Спасибо сказали: 229 раз(а) Репутация: ![]() ![]() ![]() |
Ага, а потом делать рефакторинг приложения, если захочется добавить дополнительный поток. Лучше уж сразу deleteLater() использовать, если это не критично. Хотя я думаю, что в местах где скорость и память критичны - не используются QObject'ы.
|
|
|
BRE |
![]()
Сообщение
#20
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
Ага, а потом делать рефакторинг приложения, если захочется добавить дополнительный поток. Лучше уж сразу deleteLater() использовать, если это не критично. Хотя я думаю, что в местах где скорость и память критичны - не используются QObject'ы. Не нужно удалять объект во всех методах класса, тогда в одном месте нужно будет заменить delete на deleteLater. Если решил добавить поток, который будет работать с объектом из главного потока, там по любому нужно будет делать телодвижения для обеспечения корректного доступа к нему из нескольких потоков. ![]() |
|
|
SABROG |
![]()
Сообщение
#21
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1207 Регистрация: 8.12.2008 Из: Russia, Moscow Пользователь №: 446 Спасибо сказали: 229 раз(а) Репутация: ![]() ![]() ![]() |
Лучше, когда этих телодвижений меньше. Code less - create more.
|
|
|
igor_bogomolov |
![]()
Сообщение
#22
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
Если сейчас выполняется твоя функция (в которой удаляется какой то объект), то это говорит о том, что процессор выполняет код этой функции, а не обрабатывает события или делает что-то еще. ![]() А потом объекта уже не будет... Деструктор QObject уберет указатель на этот объект из списка parent (если он есть) и уничтожит его. Объект удалится, а сообщения для этого объекта почистятся в деструкторе QObject? Помогите тогда разобрать в таком коде В током виде приложение моментально падает, хотя из выше сказанного получается, что не должно. Если удалять через deleteLater, этого не произойдёт. Хм... Заменил QMovie на QTimer, затем на QPushButton - вылетов нет. В чем проблема с QMovie? |
|
|
BRE |
![]()
Сообщение
#23
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
Я чуть выше писал, что нельзя удалять объект из самого себя, для этого как раз подходит deleteLater.
А здесь, не явно, но именно это и происходит. Из цикла обработки событий вызывается обработчик события таймера для объекта movie, он посылает сигнал frameChanged, это разворачивается в прямой вызов метода myslot2, из которого мы убиваем объект movie. |
|
|
Litkevich Yuriy |
![]()
Сообщение
#24
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
igor_bogomolov |
![]()
Сообщение
#25
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
Понятно.
Сколько интересно подобных объектов в Qt? Вот и получается что удалять их через delete чревато, так как не известно как они реализованы, и к чему это приведёт. ![]() |
|
|
BRE |
![]()
Сообщение
#26
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
Вот и получается что удалять их через delete чревато, так как не известно как они реализованы, и к чему это приведёт. ![]() Достаточно один раз разобраться и дальше не пытаться удалять объект из слота, который инициируется сигналом этого объекта. ![]() IMHO. На самом деле если бы все было так плохо с delete, то Тролли уже давно перекрыли бы оператора delete для объекта QObject, что бы он имел такое же поведение как и deleteLater. |
|
|
igor_bogomolov |
![]()
Сообщение
#27
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
Я понимаю, что я уже придираюсь, и что это ошибки проектирования. Просто на примере с QMovie это не очевидно.
Теперь и я разобрался, буду иметь в виду ![]() Сообщение отредактировал igor_bogomolov - 25.9.2009, 20:30 |
|
|
SABROG |
![]()
Сообщение
#28
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1207 Регистрация: 8.12.2008 Из: Russia, Moscow Пользователь №: 446 Спасибо сказали: 229 раз(а) Репутация: ![]() ![]() ![]() |
Из цикла обработки событий вызывается обработчик события таймера для объекта movie, он посылает сигнал frameChanged, это разворачивается в прямой вызов метода myslot2, из которого мы убиваем объект movie. А можете мне объяснить подробней, я не разобрался? Вот мы запускаем таймер тут:
Он срабатывает при выходе из конструктора QLabel, когда заходим в цикл событий. При первом событии таймера movie удаляется, значит вместе с ним должен удалиться и таймер и краша быть не должно... В чем подводный камень? --- А похоже понял. Внутренний вызов из метода QMovie метода myslot2 и возврат в уже не валидный объект. Сообщение отредактировал SABROG - 25.9.2009, 20:53 |
|
|
BRE |
![]()
Сообщение
#29
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
Он срабатывает при выходе из конструктора QLabel, когда заходим в цикл событий. При первом событии таймера movie удаляется, значит вместе с ним должен удалиться и таймер и краша быть не должно... В чем подводный камень? DirectConnectin - подразумевает прямое связывание, т.е. грубо говоря emit signal() разворачивается в функцию:
Из eventloop'а активируется таймер объекта movie, мы попадаем в метод _q_loadNextFrame() объекта movie (!), из него идет прямой вызов метода slot2, в котором мы убиваем объект movie. После этого начинается откат из метода slot2, должны вернуться в _q_loadNextFrame объекта movie и продолжить выполнение этого метода. А movie - убит. Приплыли. |
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 18.7.2025, 20:51 |