I want to be thorough and clean up to avoid memory and object leaks.
I had the misunderstanding that Qt cleans automatically objects that go out of scope, except pointers need to be deleted manually.
In my code I have a number of QList
... example:
void someFunction()
{
QList<int> x = QList<int>() << 0 << 0 << 0 << 0;
QList<QImage> y; // filled in some way
QList<QGraphicsScene*> s;
s = otherFunction(x, y);
}
QList<QGraphicsScene*> otherFunction(QList<int>& x, const QList<QImage>& y)
{
QList<QGraphicsScene*> s;
s.push_back(this->scene()); // a few times; of course there is some processing...
return s;
}
void thirdFunction()
{
QList<int> x = QList<int>() << 0 << 0 << 0 << 0;
QList<QImage> y; // filled in some way
QList<QGraphicsScene*> s;
s = otherFunction(x, y);
for (int i = 0; i < s.size(); ++i)
{
view[i]->setScene(s.at(i)); // view is a QList<QGraphicsView*>
}
}
Called multiple times, I can see the memory increasing (seen from task manager).
Obviously when items go out of scope, they are not being deleted... I immediately suspected the list of scene pointers.
1) What is the best way to delete them ? Will
qDeleteAll(s);
in someFunction()
be enough ? Will it delete the scene pointers, as well as all the QGraphicItems
inside the scenes ? or do I need to iterate through the list of scenes, and delete all items ? Do I have to do this :
for (int i = 0; i < s.size(); ++i)
{
s.at(i).clear();
} // then
qDeleteAll(s);
2) Do I need to delete the lists of simple variables (int
, bool
) ?
What about lists of objects, like QImage
?
3) I assumed that removing an item from the scene deletes its pointer. But now I read that, after removing an item from the scene, it needs to be deleted manually. So does
scene().clear();
delete the QGraphicItem
pointers that have been added to the scene ? Or should the items be deleted as well using a delete
call ?
4) In the thirdFunction
, do I have a memory leak ? It seems like I do !!
I can't delete the scenes since I set them onto views... but what happens to the scenes that were assigned to the views already ?
How do I clean that correctly ?
1.
qDeleteAll
deletes items in a container using the C++ delete
operator. It's also stated in the Qt documentation about QGraphicsScene
destructor:
Removes and deletes all items from the scene object before destroying the scene object
So it's enough to call qDeleteAll(s)
.
2.
There is no need to delete lists of basic or Qt types like QList<int>
or QList<QImage>
as they are deleted when the list is deleted.
3.
QGraphicsScene::clear()
removes and deletes all items from the scene. So calling scene().clear();
is enough. It's equivalent to calling :
qDeletaAll( scene()->items() );
4.
Since a view does not take ownership of scene, you should delete the previously assigned scenes using deleteLater()
:
for (int i = 0; i < s.size(); ++i)
{
view[i]->scene()->deleteLater();
view[i]->setScene(s.at(i)); // view is a QList<QGraphicsView*>
}