【问题标题】:What is the best practice to create pointer in loop and deallocate memory [closed]在循环中创建指针并释放内存的最佳实践是什么[关闭]
【发布时间】:2019-06-09 15:45:54
【问题描述】:

我的 C++ 知识不太好,所以请多多关照 :)。

我的问题是关于编码方式的一般性问题。即使我下面的示例侧重于 QGraphicsScene,QTableItem 对象或任何使用指针的对象也是如此。

我正在尝试在循环中创建指针,但我面临一个明显的困难。 每次通过循环时,我都会在内存中创建一个新空间而不释放它,从而导致内存泄漏。我不知道编写这种代码的最佳实践是什么。 我在下面给你一段代码作为例子,也许你可以帮助我改进,以便我能够理解。

void MainWindows::function(){
    for(int i=0;i<10;i++){
        QGraphicsScene *sceneP =  new QGraphicsScene();
        QPixmap pixmapP(QString::fromStdString("/home/xyz/"+std::to_string(i)+".png"));
        sceneP->addPixmap(pixmapP);
        ui->graph->setScene(sceneP);
        ui->graph->show();
    }
}

这个例子非常简单,但我想要在我的应用程序中对位于 /home/xyz/1.png、/home/xyz/2.png ...等的图片进行收费。 显然,这些图片是在sceneP中加载的,然后在第二次迭代时,它们会丢失在内存中。 我的问题如下: 你知道一个简单的方法来编写这个函数而不丢失任何内存吗? 非常感谢

【问题讨论】:

  • qt 确实为您管理对象(在某些情况下,也不太了解 qt)。这更多是关于 qt 内存管理而不是 c++
  • 您没有在 QGraphicsScene() 上设置父级。例如QGraphicsScene *sceneP = new QGraphicsScene(this);
  • 设置父级后可以做 auto children = findChildren();获取所有现有 QGraphicsScene 对象的列表。
  • 你说得对,谢谢我做了我的问题的版本
  • 添加() 并没有太大变化。无论如何,请不要根据您得到的答案/cmets 更改您的问题。问题应该有你的代码损坏,修复应该进入答案

标签: c++ qt for-loop pointers memory


【解决方案1】:

Qt 提供自己的内存管理 - 为什么不从中获利?

您可以只创建一次场景对象,然后只交换像素图 - 类似于下面(请注意,这未经测试,只是为了给您一个想法):

class MainWindows
{
    QGraphicsItem* pixmap; // raw pointer: I assume ownership remains at the view
                           // object (documentation is not explicit about...), though
                           // if not: use std::unique_ptr instead...
    MainWindows(...)
        : // ...
          pixmap(nullptr)
    {
        ui->graph->setScene(new QGraphicsScene(this));
    }
};

void MainWindows::function()
{
    if(this->pixmap)
    {
        ui->graph->scene()->removeItem(pixmap);
    }

    // according to comment:
    unsigned int n = ...; // select from combo box

    QPixmap pixmapP(QString("/home/xyz/%1.png").arg(n)); // a bit more convenient
    this->pixmap = ui->graph->scene()->addPixmap(pixmapP);
    ui->graph->show();
}

或者,如果您希望每次都重新创建场景对象:

QGraphicsScene* sceneP = new QGraphicsScene();
QPixmap pixmapP(...);
sceneP->addPixmap(pixmapP);

// delete the old one
// (delete is robust against nullptr, so no check needed...)
delete ui->graph->scene(); // now dangling, but you replace it anyway

ui->graph->setScene(sceneP);
ui->graph->show();

【讨论】:

  • 非常感谢,它有效!当我将新的 QTableWidgetItem 声明为指针时,我可以做类似的事情吗? Arf 可能并不重要,因为它们不会加载很多内存
  • 只要内存管理相同,可以。如果设置项目的容器拥有所有权,则需要防止重复删除!
猜你喜欢
  • 1970-01-01
  • 2011-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-02
  • 2010-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多