Fli*_*McF 0 c++ file-io rapidxml code-formatting libcurl
这两种读取输入文件的方法有什么区别?
1)使用 'ifstream.get()'
和
2)使用vector<char>with ifstreambuf_iterator<char> (我不太了解!)
(除了使用漂亮的矢量方法的明显答案)
输入文件是XML,如下所示,立即解析为rapidxml文档.(在其他地方初始化,参见示例main函数.)
首先,让我向您展示两种编写'load_config'函数的方法,一种使用ifstream.get(),一种使用vector<char>
方法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;
}
Run Code Online (Sandbox Code Playgroud)
方法2导致另一个库的cloberred 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('\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;
}
Run Code Online (Sandbox Code Playgroud)
主要代码:
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";
Run Code Online (Sandbox Code Playgroud)
我非常确定这一切都是在一个线程中执行的,但也许有一些事情在我的理解之外.
我也担心我只修改了一个症状,而不是原因...只需更改我的文件加载功能.期待社区的帮助!
问题:为什么要从矢量转移到字符数组修复此问题?
提示:我知道rapidXML使用了一些实际上直接访问输入字符串的聪明的内存管理.
提示:上面的主要功能创建了一个动态(新)xml_document.这不在原始代码中,并且是调试更改的工件.原始(失败)代码声明了它并且没有动态分配它,但是发生了相同的问题.
完全公开的另一个提示(虽然我不明白为什么这很重要) - 在这个混乱的代码中有另一个向量实例,由rapidxml :: xml_document对象中的数据填充.
两者之间的唯一区别是vector版本正常工作,char当文件长度超过65535个字符时,数组版本会导致未定义的行为(它写入第65535 \0或65536位,这是超出范围的).
两个版本共有的另一个问题是,您将文件读入的内存寿命比生命周期短xml_document.阅读文档:
该字符串必须在文档的生命周期内持久存在.
当load_config退出时vector被破坏并释放内存.尝试访问文档会导致读取无效内存(未定义的行为).
在char阵列版本中,内存在堆栈上分配.当load_config存在时它仍然被"释放" (访问它会导致未定义的行为).但你没有看到崩溃,因为它还没有被覆盖.
| 归档时间: |
|
| 查看次数: |
3840 次 |
| 最近记录: |