Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 30
×

С++ (qt) нужно ли ЭТО очищать в деструкторе

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

если у меня есть глобальная переменная например

QStringList cols;

то нужно ли мне в деструкторе ее очищать, тоесть писать

cols.clear()

или если это не ссылочный тип (тоесть QStringList * cols = new QStringList ()) то и не нужно это очищать?

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
1 — тема важная, но вполне понятная.
2 — В жаве и шарпе, за такую штуку, как сборщик мусора приходится платить производительностью и объемом занимаемой памяти, поэтому С++ до сих пор и юзается.
3 — Во многих С++ либах сборщик мусора реализован и активно юзается (boost).
На wiki по этому поводу написано -
«Некоторые считают недостатком языка C++ отсутствие встроенной системы сборки мусора. С другой стороны, средства C++ позволяют реализовать сборку мусора на уровне библиотеки [13]. Противники сборки мусора полагают, что RAII является более достойной альтернативой. С++ позволяет пользователю самому выбирать стратегию управления ресурсами»
И вообще в нете полно статей и примеров, по поводу управления памяти в С++.

А если говорить об обнаружении утечек, то для linux советую посмотреть такую утилиту, как valgrind.

лично я думаю что это одна из самых важных и непонятных тем в С++... если бы все крутые програмеры четко знали что когда и где очищать... то возможно не создавали бы таких языков как джава и шарп

(опять таки имхо)

>> нет... это не тролинг... если я обидел кого то или его чуства к какой то технологии, то извините...

да не — просто вопросы немного детские, сорри =)

нет... это не тролинг... если я обидел кого то или его чуства к какой то технологии, то извините...

to maxdz — ну... я же новой темы не создал)

> а как можно узнать есть ли утечка или нет... для этого есть какие то спец. утилиты?

Прежде чем задать вопрос на форуме — задай вопрос в гугле. Например, поиск словосочетания «memory leak detection» покажет тебе много интересного.

это случайно не троллинг? =) как-то очень тупо =)

оффтоп
{
«Пока вы не знаете этих вещей, не используйте QT вообще»... когда то я учил так — сначала читал о языке, а потом прбовал что то делать.
Чесно говоря так мало чего у меня получалось..., а теперь делая все наоборот... сначала что то делаю... если что читаю доку (ну возможно не всегда:))..., а потом уже читаю литературу... и так производительность намного больше у меня... И это мне кажется намного лучше чем сначала перечитать тонны макулатуры, а потом начинать что то делать, забыв все что читал... Практика лучше чем теория... (ИМХО конечно же) }

а как можно узнать есть ли утечка или нет... для этого есть какие то спец. утилиты?

Я когда то юзал класс из какой то либы (GTk или qt) так там в документации тоже было написано, что в деструкторе поля чистятся... А была утечка...

В итоге я покопался, так в конструкторе был флаг булевский — типа очищять поля класса в деструкторе или нет, и по умолчанию там false было, так что стоит лишний раз глянуть на реализацию самого класса, если есть исходники (в qt например...)

У читывая, что они в описании класса написали —
QStandardItemModel: ~QStandardItemModel ()
Destructs the model. The model destroys all its items.
То скорее всего итемы чистятся в деструкторе, но я, на всякий случай все таки просмотрел исходники того же

QStandardItemModel: ~QStandardItemModel (), что бы убедится, что не будет утечек.


Это С++
Это Qt. По вопросу — будут. модель владеет айтемами. В туториале кутёвом все прекрасно описано в описании классов — не ленитесь прочитать.

А если в конструкторе модели ты задашь такой параметр как parent — то можешь и с удалением модели не запариваться — она будет удалена объектом parent автоматически во время его разрушения. Пока вы не знаете этих вещей, не используйте QT вообще.

может я не так понял..., но QStandardItemModel и QStandardItem это системные класы...

to nobody
Это С++ и тут все зависит от реализации класса QStandardItemModel, как напишешь этот класс, так и будет — удаляться или не удаляться (тот же new_author...), то есть вся ответственность ложится на разработчика (в данном случае класса QStandardItemModel), вот из-за этого в С++ часто возникает такая нехорошая штука, как утечка памяти.

Вот в Жабе и С# есть встроенный «сборщик мусора» вот он там и контролирует удаление не используемых объектов, а в С++ за всем нужно самому следить.

если уж такое бурное обсуждение этой темы то у меня назрел еще маленький вопросик

QStandardItemModel * work_model = new QStandardItemModel ();// это глобальная переменная
это ф-я
{
  QStandardItem *new_author = new QStandardItem(icon, author);
  work_model->appendRow(new_author);
}

если я пишу так delete work_model — то также освобождается память и для всех new_author которые были доданы в work_model… правильно?

Ну, я так понял в примере ни о каком new и delete речь не шла, мы работаем со статическим объектом.

Деструктор для — QStringList cols будет вызван автоматически, при окончании времени жизни статического объекта. А вот что будет ли в деструкторе вызов clear () или нет, это уже дело рук разработчиков класса QStringList. Так что я не стал бы особо парится, на счет вызова метода очистки для статического объекта, по идее в деструкторе класса он должен вызваться.

2 nobody: не нужно. учи матчасть читай доку doc.trolltech.com/...list.html#clear там нету упоминания про необходимость очистки памяти через вызов этой функции.

2 zzhou:, а теперь, чтобы окончательно запутать человека, расскажи что в случае порожденых от QObject класов «автоматическая очистка» все-таки возможна в некоторых случаях.

Я плохо сформулировал.
Имеется в виду что в одном и том же scope должно быть быть создание и освобождение — т.е. в одном методе:
{
Object *a = new Object;
someCode (a);
delete a; }

Единственное исключение — методы которые явно создают обьект (т.е. у которых название «create» и т.д.) — их вызов приравнивается к использованию new, сами они, очевидно, не удаляют. И очень желательно чтобы someCode не удалял этот обьект — иначе есть большой шанс что со временем иногда обьект не будет удалён — ну или удалён дважды. Оно обычно само собой так получается:)

спасибо всем...

maxdz — тебе отдельно, без тебя я бы этого ироничного поста не понял бы...)

> после выхода с нее (с функции) система должна очищать всю выделеную в ней память
В C/C++ нет сборщика мусора. Потому, c динамической памятью «система» сама ничего делать не будет — лишь освободит память под статически-выделенным указателем (2 или 4 байта).

А память на которую указывает указатель — придётся освобождать самому (при помощи delete, если она была выделена new или free (), если она была выделена malloc ()). А уж где её освобождать — на выходе из этой функции или в каком-либо другом месте, решай сам. Только проследи, чтобы указатель не потерялся, пока будешь прыгать по функциям.:)

Молодец. Правильно насторожился.

Задумайся вот о чем. Почему золотое правило называют золотым?

и еще один вопрос... просто насторожило это «Золотое правило — делал new — делай delete.»... А что, если я делал new в середине функции, то вроде после выхода с нее (с функции) система должна очищать всю выделеную в ней память... или мне всеравно нужно явно указывать delete?

Если не было выделения динамической памяти (а new может вызываться где-то внутри QStringList например), то освобождать не нужно.

тоесть если я не писал new то и как то очищать это не нужно... так?

Золотое правило — делал new (точнее — явно создание обьекта — как то create... у какой-то фабрики) — делай delete.

clear — не уничтожает обьекты. Он просто очищает коллекцию. Вызывать перед выходом из scope не надо. Если коллекция будет уничтожена, то вся память, которую она выделяла, будет очищена.

если глобальная переменная, то скорее всего используется на всём этапе текущего запуска (экземпляра) программы. А операционка (win/lin/macos, по поводу других не знаю) автоматически очищает память процесса и открытые системные дескрипторы.

Підписатись на коментарі