【问题标题】:Memory is delete always needed in Qt C++?Qt C++中总是需要删除内存?
【发布时间】:2015-03-05 20:32:22
【问题描述】:

我已经使用并修改了下面的示例代码:

void MyScene::mousePressEvent(QGraphicsSceneMouseEvent *event) 
{ 
myPath = new QGraphicsPathItem();
previous = event->scenePos(); 
QPainterPath p; 
p.moveTo(previous); 
myPath->setPath(p); 
this->addItem(myPath);
}

void MyScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) 
{ 
if(myPath) 
{ 
QPainterPath path = myPath->path(); 
previous = event->scenePos(); 
path.lineTo(previous); 
myPath->setPath(path); 
} 
}

它是一个简单的“草图系统”的一部分。我觉得奇怪的是指针:

QGraphicsPathItem *myPath;

不接受构造函数或允许:

myPath = new QGraphicsPathItem(this); // this code will fail - why?

我原以为这将有助于清理/删除指针。为什么这不会泄漏内存?或者是吗?我在 QTCreator 中使用了 Valgrind,它似乎没有显示任何内存泄漏。我应该在某个位置:

delete(myPath); // is this needed?

任何人都可以解释或指出何时需要删除的简明解释,请特别在 QT 中。我正在研究 QPointer 和 QSharedPointer,可能是更好的方法。

我发现 Valgrind 很难在命令行上使用 QTCreator 创建的应用程序,因为它似乎与正在创建的 GUI 对象等混淆并吐出数百行代码。在 QTCreator 中,我用简单的案例测试了 valgrind,它只指向正确的行,没有别的——要容易得多。没有上面的行:

delete(myPath); // is this needed? 

Valgrind 似乎没有显示内存泄漏。为什么?

在 QtCreator 中我可以信任 Valgrind 多少?

【问题讨论】:

  • 根据qt-project.org/doc/qt-4.8/qgraphicsscene.html#addItem 中的文档,场景“获得所有权”您通过它的项目。这意味着,当场景被销毁(场景的析构函数)时,它将被场景删除。如果您决定手动删除它,我敢打赌这将导致双重删除。为什么这显示为内存泄漏我不确定.....其他人可以接管这一点。
  • 刚刚意识到你并没有说它显示了双重删除的内存泄漏,我的错。

标签: c++ qt memory-leaks


【解决方案1】:

我不是 Qt 专家,但我认为 MyScene 继承自 QGraphicsScene。在这种情况下,addItem() 将拥有 myPath 的所有权,并在需要时将 delete 它。

只要您将QGraphicsPathItem 的所有权传递给其他对象,您就不必删除它,但在此之前您对内存负责。注意未调用addItem() 的代码路径,因为那样您可能需要调用delete。例如,如果抛出异常。

这种模式有点过时了,但在基于场景图的图形框架中仍然很常见。

【讨论】:

    猜你喜欢
    • 2013-04-13
    • 2018-04-02
    • 2017-08-18
    • 2011-10-11
    • 2019-04-21
    • 2017-02-15
    • 1970-01-01
    • 1970-01-01
    • 2016-06-29
    相关资源
    最近更新 更多