Frage

Suppose I have a 2D array full of data say 10 x 10. The contents, as well as a number of rows, can change any time. Now I want to display this data in a QTableWidget.
I use a timer with time out 1sec to refresh the table contents. In the timeout slot if I use

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]);
}

the use out new TableWidgetItem worries me. I have no reference to it and I never delete it.
Over a period of time is this a memory leak, or is this managed by Qt, pls help...

War es hilfreich?

Lösung

There is no leak, as

The table takes ownership of the item.

(From QTableWidget::setItem()).

Ownership here means that the QTableWidget will take care of deleting the item when its not longer needed, or the QTableWidget itself is destroyed. Ownership is usually documented in the Qt documentation (if not, I'd consider that a Qt bug).

Once setItem() returns from being called on the same cell, the previously set QTableWidgetItem will be deleted:

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();
}

If you're on Linux, you can also verify the behavior by running above code (without the second qDebug()) in valgrind with --leak-check=full.

Andere Tipps

From the Qt documentation:

void QTableWidget::setItem ( int row, int column, QTableWidgetItem * item ) Sets the item for the given row and column to item. The table takes ownership of the item.

This indicates that Qt will manage the memory for the object as necessary.

It will delete properly when the you add Q-objects to the cells. I was pushing thousands of C-strings in cells and watched my memory blow up. Made my "raw text data" a QString and my problem was solved.

Such problem takes place to be: Qt does not really clear the memory allocated through 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);
    }
}

This code gives 116 bytes of leakage.

We found this solution: Instead of QTableWidgetItem, you can use QLineEdit:

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

p.s. To search for leaks used Dr.memory

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top