读取xml节点列表会导致分段错误

时间:2017-09-15 20:19:29

标签: c++ xml pugixml

我尝试为我使用的游戏服务器引擎开发一个包系统,所以,一开始我读取一个XML文件并将节点添加到列表中,以便稍后使用。我可以用同样的方法创建它后读取列表。但是当我尝试从另一个文件中读取它时,它会给我分段错误。让我们看一些代码。

首先,我添加了packages.cpppackages.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
    }
}

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

pugi::xml_document packagesDoc;移动到全局范围可能会解决此问题。

pugi::xml_document超出范围并被销毁时,与该文档中的节点关联的所有xml_node个对象都将变为无效。这与STL容器中的迭代器类似 - 您可以获取std::list元素的迭代器,但是销毁list对象意味着您无法访问它们。

更好的解决方案是在这里使用除全局变量之外的其他东西 - 例如,将xml_documentstd::list<xml_node>放在Packages类中是更好的选择,但是这在某种程度上取决于您希望代码具有的结构。