В чем разница между этими двумя методами чтения входного файла?
1) Использование 'ifstream.get()'
и
2) Использование vector<char>
с ifstreambuf_iterator<char>
(менее понятно мне!)
(кроме очевидного ответа на наличие изящных векторных методов для работы)
Входной файл представляет собой XML и, как вы видите ниже, сразу же преобразуется в документ rapidxml. (инициализировано в другом месте, см. пример основной функции.)
Во-первых, позвольте мне показать вам два способа написания функции 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;
}
Метод 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('\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";
Я чертовски уверен, что все это выполняется в одном потоке, но, возможно, что-то происходит за пределами моего понимания.
Меня также беспокоит, что я исправил только симптом, а не причину... просто изменив функцию загрузки файла. Ищу помощи у сообщества!
Вопрос: Почему переход от вектора к массиву символов исправит это?
Подсказка: я знаю, что RapidXML использует умное управление памятью, которое напрямую обращается к входной строке.
Подсказка: основная функция выше создает динамический (новый) xml_document. Этого не было в исходном коде, и это артефакт отладочных изменений. Исходный (неудачный) код объявлял его и не выделял его динамически, но возникали идентичные проблемы.
Еще одна подсказка для полного раскрытия (хотя я не понимаю, почему это имеет значение) - в этом беспорядке кода есть еще один экземпляр вектора, который заполняется данными в объекте rapidxml::xml_document.
sexy
? Это показ мод? - person Nawaz   schedule 16.06.2011chars_read < 65535
является ложным, это означает, чтоchars_read == 65535
, а затем вы получаете доступ к 65535-й позиции, которая находится после конца массива. - person Yakov Galka   schedule 16.06.2011