7

ベクトルのデータをバイナリシリアル化しようとしています。以下のこのサンプルでは、​​文字列にシリアル化してから、ベクトルに逆シリアル化しますが、最初に使用したものと同じデータを取得しません。なぜそうなのですか?

vector<size_t> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);

string s((char*)(&v[0]), 3 * sizeof(size_t));

vector<size_t> w(3);
strncpy((char*)(&w[0]), s.c_str(), 3 * sizeof(size_t));

for (size_t i = 0; i < w.size(); ++i) {
    cout << w[i] << endl;
}

私は出力を取得することを期待しています

1  
2
3

代わりに出力を取得します

1
0
0

gcc-4.5.1の場合

4

4 に答える 4

4

エラーはへの呼び出しにありstrncpyます。リンク先のページから:

srcの長さがn未満の場合、strncpy()はdestの残りの部分をnullバイトで埋めます。

したがって、0シリアル化されたデータの最初のバイトが見つかった後、wのデータ配列の残りの部分にはsが埋め込まれ0ます。

これを修正するには、forループを使用するか、std::copy

std::copy( &s[0], 
           &s[0] + v.size() * sizeof(size_t), 
           reinterpret_cast<char *>(w.data()) );

std::stringIMOは、バッファーとして使用する代わりに、char配列を使用してシリアル化されたデータを保持します。

イデオネの

于 2012-07-05T23:13:30.493 に答える
2

strncpy失敗の巨大な山です。いくつかのゼロバイトがあるため、入力の早い段階で終了しますsize_t。これはNULLターミネータとして解釈され、デフォルトで構築された0のままになります。BEマシンでこのテストを実行した場合、すべてが0になります。を使用しstd::copyます。

于 2012-07-05T23:13:49.220 に答える
-1

このベクトルを文字列にシリアル化するには、最初にこのベクトルの各要素をintからその番号の同じASCII表現を含む文字列に変換する必要があります。この操作はintから文字列へのシリアル化と呼ぶことができます。

したがって、たとえば、整数が10桁​​であると仮定すると、次のことができます。

// create temporary string to hold each element
char intAsString[10 + 1];

次に、整数を文字列に変換します

sprintf(intAsString, "%d", v[0]);

また

itoa( v[0], intAsString, 10 /*decimal number*/ );

ostringstreamと<<演算子を利用することもできます

intAsStringとv[0]のメモリの内容を見ると、それらは大きく異なります。最初の文字には10進数システム(基数10)のv [0]の値を表すascii文字が含まれ、v[0]には数値の2進表現(コンピューターが数値を格納する方法であるため)。

于 2012-07-05T23:13:53.290 に答える
-1

最も安全な方法は、ベクトルをループして、値を個別にサイズ3 * sizeof(size_t)のchar配列に格納することです。そうすれば、ベクトルクラス実装の内部構造に依存する必要がなくなります。

于 2012-07-05T23:33:57.643 に答える