我尝试为我使用的游戏服务器引擎开发一个包系统,所以,一开始我读取一个XML文件并将节点添加到列表中,以便稍后使用。我可以用同样的方法创建它后读取列表。但是当我尝试从另一个文件中读取它时,它会给我分段错误。让我们看一些代码。
首先,我添加了packages.cpp
和packages.h
。他们看起来像:
packages.cpp
#include "otpch.h"
#include "packages.h"
#include "pugicast.h"
#include "tools.h"
#include "events.h"
std::list<pugi::xml_node> packages;
Packages::Packages()
{
//
}
bool Packages::loadFromXml()
{
std::string packagesPath = "data/packages";
pugi::xml_document packagesDoc;
pugi::xml_parse_result packagesResult = packagesDoc.load_file((packagesPath + std::string("/packages.xml")).c_str());
if (!packagesResult) {
printXMLError("Error - BaseEvents::loadFromXml", "data/packages/packages.xml", packagesResult);
return false;
}
for (auto packageNode : packagesDoc.child("packages").children()) {
packages.push_back(packageNode);
}
// I can read the list here without any problem.
return true;
}
packages.h:
extern std::list<pugi::xml_node> packages;
class Packages
{
public:
Packages();
bool loadFromXml();
};
然后我将此代码添加到启动文件
Packages g_packages;
void mainLoader()
{
std::cout << ">> Loading packages" << std::endl;
if (!g_packages.loadFromXml()) {
startupErrorMessage("Unable to load packages!");
return;
}
}
最后,我尝试在另一个文件中迭代这个列表:
#include "packages.h"
bool Events::loadFromPackages()
{
for (auto& package : packages) {
std::cout << package.name() << std::endl; // segmentation fault
}
}
感谢任何帮助。
答案 0 :(得分:0)
将pugi::xml_document packagesDoc;
移动到全局范围可能会解决此问题。
当pugi::xml_document
超出范围并被销毁时,与该文档中的节点关联的所有xml_node
个对象都将变为无效。这与STL容器中的迭代器类似 - 您可以获取std::list
元素的迭代器,但是销毁list
对象意味着您无法访问它们。
更好的解决方案是在这里使用除全局变量之外的其他东西 - 例如,将xml_document
和std::list<xml_node>
放在Packages
类中是更好的选择,但是这在某种程度上取决于您希望代码具有的结构。