C++ 从文件读取RapidXML-这里有什么问题?

C++ 从文件读取RapidXML-这里有什么问题?,c++,file-io,libcurl,rapidxml,code-formatting,C++,File Io,Libcurl,Rapidxml,Code Formatting,这两种读取输入文件的方法有什么区别 1) 使用'ifstream.get()' 及 2) 使用向量和ifstreambuf_迭代器(我不太了解!) (除了使用漂亮的向量方法的明显答案) 输入文件是XML,如下所示,它立即解析为rapidxml文档。(在别处初始化,参见示例主函数。) 首先,让我向您展示两种编写“load_config”函数的方法,一种使用ifstream.get(),另一种使用vector 方法1ifstream.get()提供工作代码和安全的rapidXML文档对象: rapi

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

1) 使用
'ifstream.get()'

2) 使用
向量
ifstreambuf_迭代器
(我不太了解!)

(除了使用漂亮的向量方法的明显答案)

输入文件是XML,如下所示,它立即解析为rapidxml文档。(在别处初始化,参见示例主函数。)

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

方法1
ifstream.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++] = '\0';

   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;
}
rapidxml::xml\u document*load\u config(rapidxml::xml\u document*doc){
ifstream myfile(“inputfile”);
//读取配置文件
char ch;
字符缓冲区[65536];
大小字符读取=0;
while(myfile.get(ch)&(chars_read<65535)){
缓冲区[chars_read++]=ch;
}
缓冲区[chars_read++]='\0';

cout这两者之间的唯一区别是
向量
版本工作正常,
字符
数组版本在文件长度超过65535个字符时会导致未定义的行为(它将
\0
写入65535或65536位置,这是越界的)

两个版本都存在的另一个问题是,将文件读入的内存比
xml\u文档
的寿命短。请阅读文档:

该字符串必须在文档的生存期内保持不变

load\u config
退出时,
向量
被破坏,内存被释放。尝试访问文档会导致读取无效内存(未定义行为)


char
数组版本中,在堆栈上分配内存。当
load\u config
存在时,内存仍处于“释放”状态(访问它会导致未定义的行为)。但您看不到崩溃,因为它尚未被覆盖。

两者之间的唯一区别是
向量
版本工作正常,
字符
数组版本在文件长度超过65535个字符时会导致未定义的行为(它将
\0
写入65535或65536位置,超出范围)

两个版本都存在的另一个问题是,将文件读入的内存比
xml\u文档
的寿命短。请阅读文档:

该字符串必须在文档的生存期内保持不变

load\u config
退出时,
向量
被破坏,内存被释放。尝试访问文档会导致读取无效内存(未定义行为)


char
数组版本中,在堆栈上分配内存。当
load\u config
存在时,内存仍处于“释放”状态(访问它会导致未定义的行为)但是你看不到崩溃,因为它还没有被覆盖。

其中的
sexy
是什么?这是一场时装秀吗?因为唯一的区别是如何从文件中读取数据,所以这些问题似乎是相关的:作为一个健全性检查,你能设置调试器来检查从&buffer[0]开始的内存吗对于parse()之前和之后的调用看看它们是否在所有情况下都是一样的?你仍然有这个bug。当你因为
chars_-read<65535
为false而退出循环时,这意味着
chars_-read==65535
然后你访问65535位置,这是数组末尾的一个位置。谢谢ybungalobill。不应该低估这一点。注意到,感谢你,还有修正了。这里面的
sexy
是什么?这是一场时装秀吗?因为唯一的区别是如何从文件中读取数据,所以这些问题似乎是相关的:作为一个健全性检查,您是否可以设置调试器来检查从&buffer[0]开始的内存,以检查parse()之前和之后的调用看看它们是否在所有情况下都是一样的?你仍然有这个bug。当你因为
chars_-read<65535
为false而退出循环时,这意味着
chars_-read==65535
然后你访问65535位置,这是数组末尾的一个位置。谢谢ybungalobill。不应该低估这一点。注意到,感谢你,还有修复。这当然是答案。最终发现字符数组版本也有问题。函数中的“static”关键字和最终将缓冲区范围移动到主解决问题。谢谢!这当然是答案。最终发现字符数组版本也有问题。函数中的“static”关键字和最终的moving缓冲区范围到主要解决的问题。谢谢!
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('\0');

   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";