0

ostringstreamバイナリ データを取得してオブジェクト に書き込む次のスニペットを考えてみましょう。

unsigned char* payload;
unsigned long  size;

GetData(&payload, &size);

std::cout << md5(payload, size) << std::endl;

std::ostringstream stream;
stream.write((const char*)payload, size);

std::cout << md5(payload, size) << std::endl;

問題は、出力された 2 つのハッシュ値が互いに異なっpayloadていることです。これは、変更されたことを意味します。streamを使用してバイナリモードで開いてみましstd::ostringstream stream(std::ios::out | std::ios::binary)たが、違いはありませんでした。とにかく、違いがあるとは思っていませんでした。

もう 1 つの事実は、プログラムを再実行するたびに、2 番目の print ステートメントから異なるチェックサムを取得することです。最初のハッシュは常に同じです。

では、バイナリ データを ostringstream に正しく書き込むにはどうすればよいでしょうか。const char*問題は(GetDataメソッドがunsigned char**最初のパラメーターとして取る)へのキャストでしょうか?

更新:コメントに照らして、ここにいくつかの説明があります:

  • 元のデータと書き込まれたデータのバイナリ差分を比較すると、書き込まれたデータがいくつかの場所で右にシフトしている (24 バイト) ことがわかりました。また、最初にいくつかのバイトが追加されています。キャストの関係もあると思います。
  • GetDataと実際の書き込みの間にこれ以上のコードはありません。
  • GetData は、呼び出し後のチェックサムが正しいため、正しく機能します (チェックサムがどうあるべきかはわかっています)。
  • のため、コンパイル可能なコードを投稿できませんGetData。必要ではありません。問題をwriteが呼び出された行に切り分けました。
  • システムの詳細は次のとおりです。Ubuntu 12.04 64 ビットの gcc バージョン 4.6.3
4

1 に答える 1

0

問題の謎は、データのサイズであることが判明しました。

さまざまなサイズ値を試した結果、ostringstreamの内部バッファが約 65KB、正確には 65504 バイトであることがわかりました。サイズが大きくなると、奇妙なシフトや不自由なバイトが発生します。

回避策は次を使用することです。

stream.rdbuf()->pubsetbuf((const char*)payload, payloadSize)

メソッドの代わりにwrite。ただし、このスコープが終了すると、ペイロードは無効になり、stream他の場所では使用できなくなります。私の場合、他の場所で使用する必要がありました。

これは、次のことを示しました。

  • ostringstream問題はハッシュやその他のものではなく、問題であるということは確かに正しかったです。
  • STL の文字列ストリームには、明らかにデフォルトのバッファ サイズ制限があります。これは、将来覚えておく必要があります。
于 2013-05-21T14:20:20.543 に答える