Нарушение доступа C++ rapidxml через определенное время (Visual Studio 2013)
Я использовал отличную библиотеку rapidxml для чтения и использования информации из файлов XML для хранения информации кат-сцены для игры, которую я программирую на C++. Я столкнулся со странной проблемой,
Я начинаю с загрузки файла XML в rapidxml::xmldocument<>* из std::ifstream* XMLFile
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();
мой xutscene xml-файл состоит из "частей", и в начале я хочу загрузить все эти части (которые все 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());
}
}
В последней строке выводится "имя детали, добавленной в 1: деталь" на консоль. По какой-то причине проблема заключается в том, что всякий раз, когда я пытаюсь получить доступ к вектору и печатать одно и то же имя той же конкретной части, а не как часть этого метода, к имени можно получить доступ, но это просто случайная строка букв и цифр. Кажется, что по какой-то причине rapidxml удаляет все после того, как мой метод загрузки завершен. Я все еще новичок в публикации на stackru, поэтому, если вам нужна дополнительная информация, просто спросите, спасибо!
1 ответ
Rapidxml - это анализатор XML на месте. Изменяет исходный строковый буфер (content
в вашем случае) для форматирования токенов с нулевым символом в конце, таких как имена элементов и атрибутов. Во-вторых, срок службы узлов дерева, на которые ссылаютсяparts
элементы определяются как xml_document (currscene
) пример.
Держать currscene
а также content
экземпляры вместе с вектором, это также будет поддерживать векторные элементы живыми. например:
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('\0');
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], не гарантированно завершается нулем, рекомендуется скопировать содержимое строки в std::vector<char>
,