RapidXML从文件中读取-这里有什么问题

RapidXML reading from file - what is wrong here?

本文关键字:这里 什么 问题 读取 文件 RapidXML      更新时间:2023-10-16

这两种读取输入文件的方法有什么区别?

1) 使用'ifstream.get()'

2) 使用vector<char>ifstreambuf_iterator<char>(我不太理解!)

输入文件是XML,如下所示,它会立即解析为一个rapidxml文档。(在其他地方初始化,请参阅主功能示例。)

首先,让我向您展示两种编写"load_config"函数的方法,一种是使用ifstream.get(),另一种使用vector<char>

方法1ifstream.get()提供了工作代码和一个安全的rapidXML文档对象:

rapidxml::xml_document<> *load_config(rapidxml::xml_document<> *doc){
   ifstream myfile("inputfile");
   //read in config file
   char ch;
   char buffer[65536];
   size_t chars_read = 0;
   while(myfile.get(ch) && (chars_read < 65535)){
      buffer[chars_read++] = ch;
   }
   buffer[chars_read++] = '';
   cout<<"clearing old doc"<<endl;
   doc->clear();
   doc->parse<0>(buffer);
   //debug returns as expected here
   cout << "load_config: Name of my first node is: " << doc->first_node()->name() << "n";
   return doc;
}

方法2导致另一个库阻塞了rapidXML文档,特别是对curl_global_init(curl_global_SSL)的调用[参见下面的主代码],但我现在还没有将其归咎于curl_global_init。

rapidxml::xml_document<> *load_config(rapidxml::xml_document<> *doc){
   ifstream myfile("inputfile");
   vector<char> buffer((istreambuf_iterator<char>(inputfile)), 
                istreambuf_iterator<char>( ));
   buffer.push_back('');
   cout<<"file looks like:"<<endl;  //looks fine
   cout<<&buffer[0]<<endl;
   cout<<"clearing old doc"<<endl;
   doc->clear();
   doc->parse<0>(&buffer[0]);
   //debug prints as expected
   cout << "load_config: Name of my first node is: " << doc->first_node()->name() << "n";
   return doc;
}

主代码:

int main(void){
   rapidxml::xml_document *doc;
   doc = new rapidxml::xml_document;
   load_config(doc);
   // this works fine:
   cout << "Name of my first node is: " << doc->first_node()->name() << "n"; 
   curl_global_init(CURL_GLOBAL_SSL);  //Docs say do this first.
   // debug broken object instance:
   // note a trashed 'doc' here if using vector<char> method 
   //  - seems to be because of above line... name is NULL 
   //    and other nodes are now NULL
   //    causing segfaults down stream.
   cout << "Name of my first node is: " << doc->first_node()->name() << "n"; 

我非常确信这一切都是在一个线程中执行的,但也许有一些事情超出了我的理解范围。

我还担心我只是解决了一个症状,而不是原因。。。只需更改我的文件加载函数。向社区寻求帮助!

问题:为什么从矢量移动到字符数组会解决这个问题?

提示:我知道rapidXML使用了一些巧妙的内存管理,可以直接访问输入字符串。

提示:上面的主函数创建了一个动态的(新的)xml_document。这不在原始代码中,并且是调试更改的工件。原始的(失败的)代码声明了它,并没有动态分配它,但出现了相同的问题。

完全公开的另一个提示(尽管我不明白为什么它很重要)-在这混乱的代码中有另一个向量实例,它由rapidxml::xml_document对象中的数据填充。

两者之间唯一的区别是,当文件长度超过65535个字符时,vector版本工作正常,而char数组版本会导致未定义的行为(它将写入65535或65536个位置,这两个位置超出了界限)。

两个版本的另一个常见问题是,将文件读取到比xml_document寿命更短的内存中阅读文档:

该字符串必须在文档的生存期内持续存在。

load_config退出时,vector被破坏并且存储器被释放。尝试访问文档导致读取无效内存(未定义的行为)。

char阵列版本中,内存是在堆栈上分配的。当load_config存在时,它仍然是"释放的"(访问它会导致未定义的行为)。但是你看不到崩溃,因为它还没有被覆盖。