2012-07-05 17 views
5

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

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 

を取得する代わりに、出力に(gcc-4.5.1上)

1 
0 
0 

を得ることを期待

+0

@マーク:そうは思わない。 –

答えて

4

エラーがstrncpyへの呼び出しです。リンクされたページから:

SRCの長さはstrncpy(未満N場合)NULLバイトとDESTの残りの部分をパッド。シリアル化されたデータの最初0バイトが発見された後

したがって、wのデータ配列の残りは0 Sで埋められます。

だけシリアル化されたデータを保持するcharアレイを使用し、代わりにバッファのようstd::stringを使用する、IMO、この問題を解決forループを使用して、またはstd::copy

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

します。 ideone

+0

'strncpy'をうまくキャッチできませんでした。私はその"機能 "について知らなかったので、彼のコードがうまくいかなかったのは困惑していました。 –

+0

ありがとうございます。なぜstd :: copyがmemcpyより優れているのですか? – typedef

+0

整数の配列をコピーするので、同じことができます。しかし、ベクトルにあるリソースを管理するオブジェクトが含まれているとしましょう。 memcpyは、オブジェクトのビット単位のコピーを実行します。これは、コピーする方法ではない可能性が最も高いです。一方、std :: copyは、オブジェクトが正しくコピーされていることを保証する代入演算子を呼び出します。 – Praetorian

2

strncpy

Exampleは失敗の巨大な山です。 size_tにはゼロバイトが含まれているため、NULLターミネータとして解釈され、デフォルトの0として残ります。このテストをBEマシンで実行すると、すべて0になります。std::copyを使用してください。

-1

このベクトルを文字列にシリアライズするには、まずこのベクトルの各要素をintからその数値のASCII表現を含む文字列に変換する必要があります。この操作はintのシリアル化文字列に。

は、したがって、たとえば、整数と仮定すると、我々は

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

その後、あなたはまた、利用することができます

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

または

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

整数を文字列に変換できる10桁ですと< <オペレーター

intAsStringとv [0]のメモリー内容を見ると、それらは非常に異なります。最初に10進数のシステム(基数10)のv [0]の値を表すASCII文字が含まれています。 [0]には数値のバイナリ表現が含まれています(これは、コンピュータが数値を格納する方法なので)。

+1

彼はテキストシリアライズではなく、バイナリシリアル化を望んでいることは明らかです。また、 'sprintf'と' itoa'はC++のコードですか? –

+0

よく彼は出力を保持するために文字列を作ったので、私は彼がテキストシリアル化を望んでいると思ったのです。 コメントありがとうございました:) –

+0

いいえ、文字列はベクトルにコピーされ、ベクトルは出力を保持します。文字列は単なるバイナリバッファです。 –

-1

最も安全な方法は、ベクトルをループして、値を3 * sizeof(size_t)のchar配列に個別に格納することです。このようにして、ベクタークラスの実装の内部構造に依存することはありません。

+0

ベクトルと文字列は、C++ 11ではパディングなしで連続していることが保証されているため、問題はありません。 –

関連する問題