入力ファイルを読み取るこれら 2 つの方法の違いは何ですか?
1) 使用'ifstream.get()'
と
2) vector<char>withの使用ifstreambuf_iterator<char> (私にはあまり理解されていません!)
(気の利いたベクトルメソッドを使用するという明白な答えを除いて)
入力ファイルは XML であり、以下に示すように、すぐに rapidxml ドキュメントに解析されます。(他の場所で初期化されます。メイン関数の例を参照してください。)
最初に、'load_config' 関数を記述する 2 つの方法を紹介します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++] = '\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 では、別のライブラリ (具体的には curl_global_init(CURL_GLOBAL_SSL) の呼び出し [以下のメイン コードを参照]) によってクローバー化された rapidXML ドキュメントが生成されますが、まだ 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 を作成します。これは元のコードにはなく、変更をデバッグした結果です。元の (失敗した) コードはそれを宣言し、動的に割り当てませんでしたが、同じ問題が発生しました。
完全な開示のためのもう 1 つのヒント (なぜそれが重要なのかはわかりませんが) - このコードの混乱には、rapidxml::xml_document オブジェクトのデータによって取り込まれたベクトルの別のインスタンスがあります。