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

问题描述 投票:1回答:1

下面是加载文件的代码。在按钮单击事件中,调用加载函数,返回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);


}
qt tinyxml2
1个回答
1
投票

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

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

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

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

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

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

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

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

希望这可以帮助。

© www.soinside.com 2019 - 2024. All rights reserved.