Передача указателя от одной функции к другой возвращает адрес, но доступ к нему вызывает ошибку сегментации

Ниже приведен код загрузочного файла. При событии нажатия кнопки вызывается функция загрузки, которая возвращает переменную-указатель XMLElement (возвращается действительный адрес), но не может получить доступ к членам XMlElement с помощью оператора -> из-за ошибки сегментации.

XMLElement *XMLUtilities::load(string filepath)
{
    XMLDocument doc;
    char *cstr = new char[filepath.length() + 1];
    strcpy(cstr, filepath.c_str());
    XMLError err=doc.LoadFile(cstr);
    XMLElement *root=nullptr;
    if(err==XML_ERROR_FILE_NOT_FOUND)
    {
        return nullptr;
    }
    else
    {
         root=doc.FirstChildElement();
         cout<<root->Name();
        return root;
    }

}
Ниже приведен код для нажатия кнопки.

`void MainWindow::on_pushButton_clicked()
{
   XMLUtilities util;
   QString filepath=QFileDialog::getOpenFileName(this,"open A file","C://");
   string str=filepath.toStdString();
   XMLElement *doc=util.load(str);
   cout<<&doc;   **/prints a address location **
   cout<<doc->Name();  **/segmentation fault occurs**
   if(doc)

   {

       QMessageBox::information(this,"success",filepath);
      // util.traverse(root);
   }
   else
       QMessageBox::information(this,"fail",filepath);


}

1 ответ

Решение

А.С. @ Сами Кухмонен указал в комментарии, проблема в том, что при методе MainWindow.Функция on_pushButton_clicked() завершена, все локальные переменные уничтожены, включая doc. Это уничтожает все узлы, элементы... и т. Д. Внутри документа, включая, конечно, корневой узел.

Самое простое решение - вернуть документ, а не только корневой элемент.

XMLDocument XMLUtilities::load(string filepath)
{
    XMLDocument doc;
    // ...
    return doc;
}

К сожалению, для этого примера это невозможно, поскольку авторы tinyxml2 считали, что было бы неэффективно разрешать копирование всего документа в памяти (что хорошо).

Единственная возможность, о которой я могу думать, - это на самом деле читать XML в XMLUtilities.load () и возвращает указатель на корневой объект ваших собственных классов, а не XMLNode или XMLElement.

Например, если вы читали информацию об автомобилях, например:

<cars>
    <car plate="000000">
        <owner ...
    </car>
    ...
</cars>

Вы бы вернули указатель на класс CarsList, который будет представлять корневой элемент cars. Следуя вашему коду, этот указатель будет иметь значение nullptr, если файл не найден или данные не могут быть получены.

Надеюсь это поможет.

Другие вопросы по тегам