2016-08-24 2 views
3

Так что у меня класс с именем AppointmentSchedule который имеет следующий тип:Вызывает ли QList вызов функции очистки памяти динамически выделенных объектов, которые хранятся в QList?

namespace Ui { 
class AppointmentSchedule; 
} 

class AppointmentSchedule : public QWidget 
{ 
    Q_OBJECT 

public: 
    explicit AppointmentSchedule(QWidget *parent = 0); 
    ~AppointmentSchedule(); 
    Ui::AppointmentSchedule *ui; 
}; 

ui этого класса состоит из двух объектов типа QLabel и двух объектов типа QDateTimeEdit. Во внешнем классе мне нужно иметь QList динамически выделенных объектов типа AppointmentSchedule. Я добавлю динамически выделенные объекты в QList, как показано ниже.

QList<AppointmentSchedule*> scheduleList; 

foreach (QDate date, dates) 
{ 
    AppointmentSchedule * newSchedule = new AppointmentSchedule(this);//Allocation of memory 
    QDateTime sDateTime(date, QTime(8, 0, 0)); 
    newSchedule->ui->appointmentStartDateTimeEdit->setDateTime(sDateTime); 
    QDateTime eDateTime(date, QTime(8, 15, 0)); 
    newSchedule->ui->appointmentEndDateTimeEdit->setDateTime(eDateTime); 
    scheduleList.append(newSchedule); 
} 

Если я называю clear() функцией QList как это:

scheduleList.clear(); 

Будет ли освободить всю память я выделил?

Спасибо.

ответ

2

Будет ли он освобождать всю память, которую я выделил?

No, clear() удалить все предметы из списка. В вашем случае эти предметы являются указателями на объектах AppointmentSchedule.

Поскольку вы устанавливаете родительский объект для объектов AppointmentSchedule, эти объекты будут удалены, когда их родитель будет уничтожен. Вот почему в вашем случае нет утечки памяти.

1

Будет ли он освобождать всю память, которую я выделил?

Нет, вы объявили список указателей к AppointmentSchedule объектов. Когда вы вызываете clear, эти указатели будут удалены, но память, на которую они указали, останется нетронутой, так что вы получите утечку памяти.

Чтобы освободить сами объекты, использовать или смарт-указатели (как std::unique_ptr и std::shared_ptr) или удалить их вручную в любом виде foreach цикла перед вызовом clear().

Edit:

В этом случае не будет никакой утечки памяти в иерархии объектов Qt будет заботиться о правильном уничтожении объекта. См. Ответ Кирилля.

+0

Спасибо, я скоро приму ваш ответ. Я действительно следовал тому, что вы сказали о том, чтобы вручную удалить их даже до того, как вы написали ответ. Итак, на этом мы согласны. :) –

+1

Но в представленном коде отсутствует утечка памяти. Объекты AppointmentSchedule имеют родительский элемент, поэтому эти объекты будут удалены, когда родительский объект будет уничтожен. –

+1

@ the_naive Также обратите внимание на ответ Кирилла. Вы устанавливаете родительские имена non-nullptr для своих объектов, поэтому деструктор родителя удалит их, и вам не нужно будет удалять их вручную. Это особенность иерархии объектов Qt и является распространенным способом удаления вложенных виджетов. – Sergey

0

Поскольку вы используете указатели: Чтобы избежать утечки памяти, вам нужно удалить каждый указатель, например, с:

foreach(auto element, scheduleList) 
{ 
    delete element; 
} 

Кроме того, если вы используете родительское свойство в ваших AppointmentSchedule элементов, они автоматически удаляются при родительское удаление.

Что касается самого списка: Если вы хотите хранить большие объекты (не указатели) в списке, вызывая .clear() удаляет только доступные элементы, но это не обязательно изменять размер контейнера.Если бы это делалось каждый раз, когда вы его вызывали, это было бы неэффективно.

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

+0

['qDeleteAll'] (http://doc.qt.io/qt-5/qtalgorithms.html#qDeleteAll-1) - удобный метод для удаления всех объектов в контейнере –

+0

@king_nak +1 для этой идиомы – Veenkar