清理 QList 和 QGraphicsScene 以避免内存泄漏
Cleaning up QList and QGraphicsScene to avoid memory leaks
我想彻底清理以避免内存和对象泄漏。
我的误解是 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:
Removes and deletes all items from the scene object before destroying
the scene object
所以调用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*>
}
我想彻底清理以避免内存和对象泄漏。
我的误解是 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:
Removes and deletes all items from the scene object before destroying the scene object
所以调用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*>
}