Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt memory management for containers

I know there is many questions about memory management in Qt. Also I read these SO questions:

  • Memory Management in Qt
  • Memory management in Qt?
  • Qt memory management. What's wrong?

But in my case, I confused again!

I have a QTableWidget with name myTable. I add run-time widgets to it by setCellWidget:

void MyClass::build()
{
    for (int i=LOW; i<HIGH; i++)
    {
        QWidget *widget = new QWidget(myTable);
        //
        // ...
        //
        myTable->setCellWidget(i, 0, widget);
    }
}

Then, I delete all items like below:

void MyClass::destroy()
{
    for (int i = myTable->rowCount(); i >= 0; --i)
        myTable->removeRow(i);
}

These methods call many times during long time. And myTable as the parent of those widgets will live along program's life-time.

Dose method destroy() release memory quite and automatically? Or I have to delete allocated widgets myself like below?

void MyClass::destroy2() // This maybe causes to crash !!
{
    for (int i = myTable->rowCount(); i >= 0; --i)
    {
        QWidget *w = myTable->cellWidget(i, 0);
        delete w;
        myTable->removeRow(i);
    }
}
like image 467
masoud Avatar asked Feb 05 '12 13:02

masoud


2 Answers

Generally speaking, when in doubt or confused about how to use a class, consult the documentation that should've came with it. Fortunately, QTableWidget::setCellWidget() does in fact come with documentation:

void QTableWidget::setCellWidget ( int row, int column, QWidget * widget )

Sets the given widget to be displayed in the cell in the given row and column, passing the ownership of the widget to the table [emphasis mine]. If cell widget A is replaced with cell widget B, cell widget A will be deleted. For example, in the code snippet below, the QLineEdit object will be deleted.

    setCellWidget(index, new QLineEdit);
    ...
    setCellWidget(index, new QTextEdit);

After the call to myTable->setCellWidget(), the table now owns the widget you passed into it. That means that myTable is responsible for deleting the widgets you pass to setCellWidget(). You don't need to do delete w; when you're removing rows. Your first destroy() function should be sufficient.

like image 100
In silico Avatar answered Sep 22 '22 06:09

In silico


From the documentation:

void QTableWidget::setCellWidget ( int row, int column, QWidget * widget )

Sets the given widget to be displayed in the cell in the given row and column, passing the ownership of the widget to the table.

If cell widget A is replaced with cell widget B, cell widget A will be deleted. For example, in the code snippet below, the QLineEdit object will be deleted.

That is, you don't clean up manually, as freeing of resources happens automatically down the Qt object tree, of which your widget has become a part.

like image 31
Kerrek SB Avatar answered Sep 21 '22 06:09

Kerrek SB