I try to develop a package system for a game server engine i use, so, upon start i read a XML file and add the nodes to a list so i can use later. I can read the list after i created it, in same method. But when i try to read it from another file, it will give me segmentation fault. Lets see some code.
First, I have added a packages.cpp
and packages.h
. They look like:
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();
};
Then I add this code to the startup file
Packages g_packages;
void mainLoader()
{
std::cout << ">> Loading packages" << std::endl;
if (!g_packages.loadFromXml()) {
startupErrorMessage("Unable to load packages!");
return;
}
}
And finally, I try to iterate this list like this in another file:
#include "packages.h"
bool Events::loadFromPackages()
{
for (auto& package : packages) {
std::cout << package.name() << std::endl; // segmentation fault
}
}
Thankful for any help.
Moving
pugi::xml_document packagesDoc;
to global scope will probably solve this issue.When
pugi::xml_document
goes out of scope and is destroyed, allxml_node
objects associated with nodes from that document become invalid. This is similar to iterators in STL containers - you can get iterators tostd::list
elements, but destroying thelist
object means that you can't access them.It is likely that a better solution is to use something other than globals here - for example, maybe putting both
xml_document
andstd::list<xml_node>
inside thePackages
class is a better option, but this somewhat depends on the structure you want your code to have.