передача указателя от одной функции к другой возвращает адрес, но доступ к нему вызывает ошибку сегментации - PullRequest
0 голосов
/ 02 сентября 2018

ниже - код для файла загрузки. При событии щелчка кнопки вызывается функция загрузки, которая возвращает переменную указателя 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 Ответ

0 голосов
/ 04 сентября 2018

AS @Sami Kuhmonen указал в комментарии, проблема в том, что когда метод MainWindow . on_pushButton_clicked () завершен, все локальные переменные уничтожаются, включая документ . Это уничтожает все узлы, элементы ... и т. Д. Внутри документа, включая, конечно, корневой узел.

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

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 в случае, если файл не найден или данные не могут быть получены.

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

...