C++ 从文件读取RapidXML-这里有什么问题?
这两种读取输入文件的方法有什么区别 1) 使用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
'ifstream.get()'
及
2) 使用向量
和ifstreambuf_迭代器
(我不太了解!)
(除了使用漂亮的向量方法的明显答案)
输入文件是XML,如下所示,它立即解析为rapidxml文档。(在别处初始化,参见示例主函数。)
首先,让我向您展示两种编写“load_config”函数的方法,一种使用ifstream.get()
,另一种使用vector
方法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++] = '\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";