清理QList和QGraphicsScene以避免内存泄漏

Cleaning up QList and QGraphicsScene to avoid memory leaks

本文关键字:内存 泄漏 QList QGraphicsScene 清理      更新时间:2023-10-16

我想彻底清理,以避免内存和对象泄漏。

我有一个误解,Qt自动清除超出作用域的对象,除了指针需要手动删除。

在我的代码中,我有一些QList…例子:

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*>
    }
}

多次调用,我可以看到内存增加(从任务管理器中看到)。

显然,当项超出作用域时,它们并没有被删除…我立刻怀疑了场景指示列表。

1)删除它们的最好方法是什么?将

qDeleteAll(s);

someFunction()中是否足够?它会删除场景指针,以及场景内所有的QGraphicItems吗?还是我需要遍历场景列表并删除所有项目?我一定要这样做吗:

    for (int i = 0; i < s.size(); ++i)
    {
        s.at(i).clear();
    } // then
    qDeleteAll(s);

2)是否需要删除简单变量(int, bool)的列表?
对象列表呢,比如QImage ?

3)我假设从场景中删除一个项目会删除它的指针。但现在我读到,从场景中删除一个项目后,它需要手动删除。那么

scene().clear();

删除已添加到场景中的QGraphicItem指针?还是应该使用delete调用来删除这些项?

4)thirdFunction中,我有内存泄漏吗?好像我有!!
我不能删除场景,因为我把它们设置在视图上…但是已经分配给视图的场景会发生什么呢?
如何正确地清理呢?

1.qDeleteAll使用c++ delete操作符删除容器中的项。Qt文档中也有关于QGraphicsScene destructor的说明:

在销毁之前从场景对象中移除并删除所有项目场景对象

所以调用qDeleteAll(s)就足够了。

2。没有必要删除基本或Qt类型的列表,如QList<int>QList<QImage>,因为它们在列表被删除时被删除。

3。QGraphicsScene::clear()从场景中移除和删除所有项目。所以调用scene().clear();就足够了。它相当于调用:

qDeletaAll( scene()->items() );

4。由于视图不占有场景的所有权,您应该使用deleteLater():

删除先前分配的场景。
for (int i = 0; i < s.size(); ++i)
{
    view[i]->scene()->deleteLater();
    view[i]->setScene(s.at(i)); // view is a QList<QGraphicsView*>
}