Утечка памяти QTableWidget или нет?

Предположим, у меня есть 2D-массив, полный данных, скажем, 10 x 10. Содержимое, а также количество строк могут измениться в любое время. Теперь я хочу отобразить эти данные в QTableWidget.
Я использую таймер с тайм-аутом в 1 секунду, чтобы обновить содержимое таблицы. В слоте тайм-аута, если я использую

void slot_timeOut()
{
    //Iterate over the rows
    //and for each cell do something like
    ui->tw_data->setItem(row, 0, new TableWidgetItem(data[row][0]);
    ui->tw_data->setItem(row, 0, new TableWidgetItem(data[row][1]);
    //...
    ui->tw_data->setItem(row, 0, new TableWidgetItem(data[row][9]);
}

использование нового TableWidgetItem меня беспокоит. У меня нет на него ссылки, и я никогда его не удаляю.
Является ли это утечкой памяти в течение определенного периода времени или этим управляет Qt, пожалуйста, помогите...


person Anjanu    schedule 24.02.2014    source источник


Ответы (4)


Утечек нет, т.

Таблица становится владельцем элемента.

(Из QTableWidget::setItem()).

Владение здесь означает, что QTableWidget позаботится об удалении элемента, когда он больше не нужен, или сам QTableWidget будет уничтожен. Право собственности обычно задокументировано в документации Qt (если нет, я бы посчитал это ошибкой Qt).

Как только setItem() вернется из вызова в той же ячейке, ранее установленный QTableWidgetItem будет удален:

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    QTableWidget widget(2, 1);
    QTableWidgetItem* foo = new QTableWidgetItem("Foo");
    widget.setItem(0, 0, foo);
    qDebug() << foo->text(); //works
    widget.setItem(0, 0, new QTableWidgetItem("Bar")); //replaces foo with bar and deletes foo
    qDebug() << foo->text(); // Undefined (usually, crash)
    widget.show();
    return app.exec();
}

Если вы работаете в Linux, вы также можете проверить поведение, запустив приведенный выше код (без второго qDebug()) в valgrind с параметром --leak-check=full.

person Frank Osterfeld    schedule 24.02.2014

Из документации Qt:

void QTableWidget::setItem (int row, int column, QTableWidgetItem * item) Устанавливает элемент для данной строки и столбца в элемент. Таблица становится владельцем элемента.

Это указывает на то, что Qt будет управлять памятью для объекта по мере необходимости.

person Chris    schedule 24.02.2014

Он будет правильно удален, когда вы добавите Q-объекты в ячейки. Я втыкал в ячейки тысячи до-строк и наблюдал, как моя память взрывалась. Сделал мои «необработанные текстовые данные» QString, и моя проблема была решена.

person 31337newbie    schedule 10.11.2016

Такая проблема имеет место быть: Qt действительно не очищает память, выделенную через QTableWidgetItem.

for( int row = 0; row < 35; row++)
{
    for(int i = 0; i < 9; i++)
    {
        QTableWidgetItem* item = new QTableWidgetItem();
        item->setText(QString::number(i));
        ui->tableWidget->setItem(row, i, item);
    }
}

Этот код дает 116 байт утечки.

Мы нашли такое решение: вместо QTableWidgetItem можно использовать QLineEdit:

 QLineEdit* tableline = new QLineEdit();
 m_qtablewidget->setCellWidget(row, column, tableline);

p.s. Для поиска утечек использовал Dr.memory

person Лео Пивоваров    schedule 20.08.2019