2008年12月05日
istringstream + binary_iarchive ではまってみる
MPIで可変サイズのデータを通信するために boost::serialization を使おうとして,受信部に下のようなコードを書いた.繰り返しサイズ不定なデータを受信するので,バッファはvector<char>にしてサイズを楽に変えられるようにしている.そして,受信したデータの復元のためにバッファをistringstreamに包んでbinary_iarchiveに投げている.細かいことを気にしないと正しく動くように見える.コンパイルも通るし.
std::vector<char> buf; for (int stage = 1; stage < procs; stage <<= 1) { // snip unsigned int s = 0; MPI_Recv(&s, 1, MPI_INT, target, TAG1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); if(s > buf.size()) buf.resize(s); MPI_Recv(&(*buf.begin()), s, MPI_BYTE, target, TAG2, MPI_COMM_WORLD, MPI_STATUS_IGNORE); std::istringstream is(&(*buf.begin()), std::ios_base::in | std::ios_base::binary); boost::archive::binary_iarchive bai(is); // snip }
が,これを動かすとbinary_iarchiveのコンストラクタでbad_allocを食らって落ちる.なぜ?
しばらく頭も回らず原因が分からなかったけどよく考えるとistringstreamのeofが判定できないんじゃないかと気づく.そのせいでbinary_iarchiveがめちゃくちゃな量を読みに行くかなんかしてメモリ不足で落ちているのではないかと.
ということで,下のように書き換えたら動いた.でもstring作る分だけ無駄だよなぁ.どうすりゃいいんだろう?
std::string str(&(*buf.begin()), s); std::istringstream is(str, std::ios_base::in | std::ios_base::binary); boost::archive::binary_iarchive bai(is);
- Comments: 0
- TrackBack (Close): -