将指针从一个函数传递到另一个 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 的根对象的指针,而不是 XMLNode 或 XML元素.
例如,如果您正在阅读有关汽车的信息,如:
<cars>
<car plate="000000">
<owner ...
</car>
...
</cars>
你会 return 一个指向 class CarsList 的指针,它代表根元素 cars .按照您的代码,如果找不到文件或无法检索数据,此指针将为 nullptr。
希望对您有所帮助。
下面是加载文件的代码。在按钮单击事件中调用加载函数,其中 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 的根对象的指针,而不是 XMLNode 或 XML元素.
例如,如果您正在阅读有关汽车的信息,如:
<cars>
<car plate="000000">
<owner ...
</car>
...
</cars>
你会 return 一个指向 class CarsList 的指针,它代表根元素 cars .按照您的代码,如果找不到文件或无法检索数据,此指针将为 nullptr。
希望对您有所帮助。