2017-09-15 62 views
1

我嘗試爲我使用的遊戲服務器引擎開發包系統,因此,在開始時,我讀取XML文件並將節點添加到列表中,以便稍後使用。我可以用相同的方法創建它之後讀取列表。但是當我嘗試從另一個文件讀取它時,它會給我分段錯誤。讓我們看看一些代碼。讀取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 
    } 
} 

感謝您的幫助。

+0

儘量不要使用全局std :: list?使用成員變量來測試您的邏輯是否全部正常工作。 – laishiekai

+0

不知道如何做到這一點。完全新的C++ :) – KrisInception

+0

把std :: list 包裝到你的Packages類中,它將成爲一個成員。 – laishiekai

回答

0

pugi::xml_document packagesDoc;移至全局範圍可能會解決此問題。

pugi::xml_document超出範圍並被銷燬時,與該文檔中的節點關聯的所有對象都變爲無效。這與STL容器中的迭代器類似 - 您可以將迭代器獲取到std::list元素,但銷燬list對象意味着您無法訪問它們。

很可能是一個更好的解決方案是用在這裏不是全局的其他東西 - 例如,也許把雙方xml_documentstd::list<xml_node>Packages類中是一個更好的選擇,但是這一定程度上取決於你希望你的代碼結構有。