一定时间后 C++ rapidxml 访问冲突(visual studio 2013)

C++ rapidxml access violation after a certain amount of time (visual studio 2013)

我一直在使用优秀的 rapidxml 库来读取和使用 XML 文件中的信息来保存我正在用 C++ 编写的游戏的过场动画信息。我 运行 遇到了一个奇怪的问题,

我首先将 XML file 从 std::ifstream* XMLFile

加载到 rapidxml::xmldocument<>*
std::stringstream buffer; //Create a string buffer to hold the loaded information
buffer << XMLFile->rdbuf(); //Pass the ifstream buffer to the string buffer
XMLFile->close(); //close the ifstream
std::string content(buffer.str()); //get the buffer as a string
buffer.clear();
cutScene = new rapidxml::xml_document<>;
cutScene->parse<0>(&content[0]);
root = cutScene->first_node();

我的过场动画 xml 文件由 "parts" 组成,一开始我想将所有这些部分(都是 xml_nodes)加载到一个向量中

//Load parts
if (parts->size() == 0) {
    rapidxml::xml_node<>* partNode = root->first_node("part");
    parts->push_back(partNode);
    for (int i = 1; i < numParts; i++) {
        parts->push_back(partNode->next_sibling());
        printf("name of part added at %i: %s.\n", i, parts->at(i)->name());
    }
}

最后一行将 "name of part added at 1: part" 打印到控制台。 问题是出于某种原因,每当我尝试访问向量并打印同一特定部分的相同名称而不是此方法的一部分时,可以访问该名称,但它只是一个随机的字母和数字字符串。似乎出于某种原因,rapidxml 在我的加载方法完成后删除了所有内容。我对在 Whosebug 上发帖还很陌生,所以如果您需要更多信息,请询问,谢谢!

Rapidxml 是 in-situ xml 解析器。它改变了原始字符串缓冲区(content 在你的例子中)来格式化以 null 结尾的标记,例如元素和属性名称。其次,parts项引用的树节点的生命周期由xml_document(currscene)实例定义。

currscenecontent 实例与向量保持在一起,这也会使向量项保持活动状态。 例如:

 struct SceneData
 {
    std::vector<char> content;
    rapidxml::xml_document<> cutScene;
    std::vector<rapidxml::xml_node<>*> parts;

    bool Parse(const std::string& text);
 };

 bool SendData::Parse(const std::string& text)
 {
       content.reserve(text.length() + 1);
       content.assign(text.begin(), text.end());
       content.push_back('[=10=]');

       parts.clear();

       try
       {
         cutScene.parse<0>(content.data());
       }
       catch(rapidxml::parse_error & err)
       {
           return false;
       }


       // Load parts.   
       rapidxml::xml_node<>* root = cutScene.first_node();      
       rapidxml::xml_node<>* partNode = root->first_node("part");
       parts->push_back(partNode);
       for (int i = 1; i < numParts; i++) {
             parts->push_back(partNode->next_sibling());
             //printf("name of part added at %i: %s.\n", i, parts->at(i)->name());
       }

       return true ;
  }

已编辑

解析器需要以 '\0 结尾的字符序列作为输入。由于 &string[0] 引用的缓冲区不保证以 null 结尾,建议将字符串内容复制到 std::vector<char>.