1

下面是加载文件的代码。在按钮单击事件中调用加载函数,该函数返回 XMLElement 指针变量。(返回有效地址)但由于发生分段错误,无法使用 ->operator 访问 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);


}
4

1 回答 1

1

正如@Sami Kuhmonen 在评论中指出的那样,问题在于当方法MainWindowon_pushButton_clicked()完成,所有局部变量都被销毁,包括doc。这会破坏文档内的所有节点、元素……等等,当然包括根节点。

最简单的解决方案是返回文档而不仅仅是根元素。

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

不幸的是,对于这个例子来说,这是不可能的,因为tinyxml2的作者认为允许在内存中复制整个文档是低效的(这是一件好事)。

我能想到的唯一可能性是实际读取XMLUtilities中的 XML 。load(),并返回指向您自己的类的根对象的指针,而不是XMLNodeXMLElement

例如,如果您正在阅读有关汽车的信息,例如:

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

您将返回一个指向CarsList类的指针,它表示根元素cars。在您的代码之后,如果找不到文件或无法检索数据,此指针将为nullptr 。

希望这可以帮助。

于 2018-09-04T10:08:52.830 回答