Создание QT TreeWidgetItem. Это утечка памяти и как я должен это правильно закодировать?

#c #qt #memory-leaks

#c #qt #утечки памяти

Вопрос:

Я загружаю файл, который мне нужен, чтобы создать строку для каждого QT TreeWidgetItem в файле. Поскольку я делаю это в цикле for, я беспокоюсь, что происходит утечка памяти. Я запустил Valgrind с этим, и, похоже, у него нет утечки памяти, но я новичок в использовании Valgrind в целом. Я беспокоюсь, что существует утечка памяти, когда заполняется DisassemblyTreeWidget, который я вызову

 DisassemblyTreeWidget->clear();
  

И когда я закончу с программой, я удалю этот объект, но я не уверен в DisassemblyListItem, который, как я думаю, может быть потерян.

Вот код, и я попытаюсь прокомментировать. Не стесняйтесь задавать вопросы в комментарии.

Если это действительно утечка памяти, как тогда я должен запрограммировать цикл для добавления элементов?

 QTreeWidgetItem *DisassemblyListItem;

void SetDisassemblyWidgetContent(Ui::MainWindow *ui , std::string Address, std::string Mneumonics ,std::string Commment)
{

    const bool __sortingEnabled = ui->DisassemblyTreeWidget->isSortingEnabled();
    ui->DisassemblyTreeWidget->setSortingEnabled(false);
     //I worry Memory Leak exists here .

    DisassemblyListItem = new QTreeWidgetItem();
    DisassemblyListItem->setText(2, QApplication::translate("MainWindow", Commment.c_str(), Q_NULLPTR));
    DisassemblyListItem->setText(1, QApplication::translate("MainWindow", Mneumonics.c_str(), Q_NULLPTR));
    DisassemblyListItem->setText(0, QApplication::translate("MainWindow", Address.c_str(), Q_NULLPTR));

    ui->DisassemblyTreeWidget->addTopLevelItem(DisassemblyListItem);
    ui->DisassemblyTreeWidget->setSortingEnabled(__sortingEnabled);


}






void GetDisassemblyWidgetContent(Ui::MainWindow *ui)
{
   ui->DisassemblyTreeWidget->clear();
   std::string Address    = "";
   std::string Mneumonics = "";
   std::string Comment    = "";

  if( (BinaryType == ArchTypeELFX86 ) ||(BinaryType == ArchTypeELFX86) ){
       ui->DisassemblyTreeWidget->header()->resizeSection(0 /*column index*/, 250 /*width*/);
       ui->DisassemblyTreeWidget->header()->resizeSection(1 /*column index*/, 380 /*width*/);
  }else{
       ui->DisassemblyTreeWidget->header()->resizeSection(0 /*column index*/, 350 /*width*/);
       ui->DisassemblyTreeWidget->header()->resizeSection(1 /*column index*/, 470 /*width*/);
  }


    std::vector<std::string> DisassemblyWidgetJSONContent;
    std::string JsonReturnData = PyEngine_ExecuteCommandWithoutParams("pygdbmi-debugger", "GetTextSection");
    //qInfo() << JsonReturnData.c_str();
    DisassemblyWidgetJSONContent = SplitJsonIntoStringsEx(JsonReturnData);


    for (int i = 0 ; i < DisassemblyWidgetJSONContent.size(); i  )
    {
     auto JsonData = json::parse(DisassemblyWidgetJSONContent[i].c_str() );
      JsonData.at("Address").get_to(Address);
      JsonData.at("Mneumonics").get_to(Mneumonics);
      JsonData.at("Comment").get_to(Comment);
      SetDisassemblyWidgetContent(ui, Address, Mneumonics, Comment);
    }

    //Not sure if this is needed, I will check potom
   DisassemblyWidgetJSONContent.clear(); // Clear Vector
   std::vector<std::string>().swap(DisassemblyWidgetJSONContent);



}
  

Ответ №1:

Я считаю, что здесь нет утечки памяти, потому что QTreeWidget получает право собственности на добавленные элементы. В документации Qt явно указано, что о setItemWidget функции. Хотя вопросы владения напрямую не рассматриваются в описании addTopLevelItem функции, скорее всего, она работает так же.

В любом случае, чтобы быть уверенным, просто укажите родительский элемент в конструкторе QTreeWidgetItem :

 DisassemblyListItem = new QTreeWidgetItem(ui->DisassemblyTreeWidget);
  

Родитель становится владельцем всех дочерних элементов и автоматически удаляет их при уничтожении.

Комментарии:

1. Я так и думал, но хотел убедиться.