Russian Qt Forum

Qt => Общие вопросы => Тема начата: NeCoder от Сентябрь 22, 2017, 12:57



Название: QListWidgetItem утекает память
Отправлено: NeCoder от Сентябрь 22, 2017, 12:57
Имею такой код. По диспетчеру смотрю что память утекает при каждом вызове функции. Вроде делаю всё правильно а память утекает. Если убрать заполнение листа то утечка прекращается. Что я делаю не так?

Код:
void MainWindow::show_report(QList<int> &iType, QStringList &strErr)
{
    // очищаю старые данные если такие есть
    if(ui->lstReport->count()>0)
    {
        qDebug() << "BEFORE ADD";
        qDebug() << ui->lstReport->count();

        for(int i=ui->lstReport->count()-1; i>0; i--)
        {
            QListWidgetItem *lstItem = ui->lstReport->takeItem(i);
            if(lstItem)
            {
                qDebug() << i;
                ui->lstReport->removeItemWidget(lstItem);
                delete lstItem;
            }
            else
            {
                qDebug() << "IM NOT ITEM!";
            }
        }

        ui->lstReport->clear();
    }



    // добавляю новые данные
    for(int i=0; i<iType.count(); i++)
    {
        QListWidgetItem *lstItem = new QListWidgetItem(iType[i]==1?QIcon(":/images/warning.png"):QIcon(), strErr[i], ui->lstReport);
        ui->lstReport->addItem(lstItem);
    }

    iType.clear();
    strErr.clear();

    qDebug() << "AFTER ADD";
    qDebug() << ui->lstReport->count();
}


Название: Re: QListWidgetItem утекает память
Отправлено: MrDron от Сентябрь 22, 2017, 13:34
Судя по документации то QListWidget::clear() должен сам все удалять и без delete takeItem(i)
Цитировать
All items will be permanently deleted.
И в переборе кстати условие i >= 0


Название: Re: QListWidgetItem утекает память
Отправлено: NeCoder от Сентябрь 22, 2017, 13:59
Цитировать
И в переборе кстати условие i >= 0
Таки да.

Судя по документации то QListWidget::clear() должен сам все удалять и без delete takeItem(i)
Изучу.

Как выяснил - память течет из-за иконки. Если иконку загрузить в конструкторе MainWindow и потом использовать уже загруженную иконку, то утечка прекращается. Может так и задумано, я без понятия. ???


Название: Re: QListWidgetItem утекает память
Отправлено: Bepec от Сентябрь 22, 2017, 14:38
А с чего вы взяли что память течёт?


Название: Re: QListWidgetItem утекает память
Отправлено: dilshodm от Октябрь 17, 2017, 22:01
Надо обратить внимание на следующий момент:

Код:
        QListWidgetItem *lstItem = new QListWidgetItem(iType[i]==1?QIcon(":/images/warning.png"):QIcon(), strErr[i], ui->lstReport);
        ui->lstReport->addItem(lstItem);


получается, что во время создания lstItem он уже вставляется в ui->lstReport, а затем еще раз вставляется с помощью команды addItem(lstItem).
как сказано в доке, повторное добавление уже существующего QListWidgetItem приводит к неопределенному поведению:
Цитировать
Warning: A QListWidgetItem can only be added to a QListWidget once. Adding the same QListWidgetItem multiple times to a QListWidget will result in undefined behavior.

Поэтому лучше создавать с родителем по умолчанию:

Код:
        QListWidgetItem *lstItem = new QListWidgetItem(iType[i]==1?QIcon(":/images/warning.png"):QIcon(), strErr[i]);
        ui->lstReport->addItem(lstItem);