将指针从一个函数传递到另一个 returns 地址但访问它会导致分段错误

passing pointer from one function to other returns a address but accessing it causes segmentation fault

下面是加载文件的代码。在按钮单击事件中调用加载函数,其中 return XMLElement 指针变量。(有效地址是 returned)但无法访问成员使用 ->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);


}

AS @Sami Kuhmonen 在评论中指出,问题是当方法 MainWindow.on_pushButton_clicked() 完成后,所有局部变量都被销毁,包括doc。这会破坏文档中的所有节点、元素...等等,当然包括根节点。

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

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

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

我能想到的唯一可能就是实际阅读XMLUtilities.load()[=中的XML 38=],和 return 指向您自己的 classes 的根对象的指针,而不是 XMLNodeXML元素.

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

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

你会 return 一个指向 class CarsList 的指针,它代表根元素 cars .按照您的代码,如果找不到文件或无法检索数据,此指针将为 nullptr

希望对您有所帮助。