Страницы

Поиск по вопросам

понедельник, 6 января 2020 г.

Динамическое выделение памяти для виджета верхнего уровня

#cpp #qt


Начал изучение Qt и на определенном этапе встал вопрос с освобождением памяти, вот
пример кода: 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Spin();
    return a.exec();
}

void Spin()
{
    QSpinBox *psb = new QSpinBox();
    psb->show();
}


Верно ли так выделять память для виджета верхнего уровня в локальной функции и нигде
далее не освобождать память для него?
    


Ответы

Ответ 1



QObject в своём деструкторе выполняет освобождение памяти дочерних элементов. Т.е. элементов, у которых Parent установлен на уничтожаемый элемент. Например: QObject* p = new QObject(); QObject* c1 = new QObject(p); QObject* c2 = new QObject(); c2->setParent(p); delete p; // Вызовет уничтожение c2, c1, p Чуть более подробнее можно почитать тут. В вашем случае при выходе из функции Spin память, адресуемая указателем psb будет утеряна, т.е. произойдёт утёчка. Самый простой способ избежать утечки - избавиться от Spin вовсе и использовать практически канонический hello world: int main() { QApplication a(argc, argv); QSpinBox psb; psb.show(); return a.exec(); } Замечу, что в этом случае используется создание QSpinBox на стеке, т.е. деструктор будет вызван автоматически. Если требуется оставить выделение памяти в куче, то нужно любым доступным образом обеспечить освобождение ресурсов psb при завершении программы. Один из возможных способов - обернуть его в умный указатель типа QSharedPointer и вернуть наружу из функции: QSharedPointer Spin() { QSharedPointer psb(new QSpinBox()); psb->show(); return psb; } Код main будет выглядеть так: int main(int argc, char *argv[]) { QApplication a(argc, argv); auto s = Spin(); return a.exec(); } В этом случае при завершении main будет выполнено уничтожение s, который хранит в себе psb.

Комментариев нет:

Отправить комментарий