2

ベクトルをシリアライズしたいと思います。そして、ベクトルのポインターを変更する方法がわかりません..簡単にするために、次のようなベクトルがあるとしましょう。

vector<char> v;

そして、私はこのポインタを持っています:

char* c = { 'v', 'e', 'c', 't', 'o', 'r' };

そして、ベクトル v の内部ポインターが私の char* c を指すようにしたいと思います。

&v[0] -> c 

cを指すようにベクトルを調整するにはどうすればよいですか? それを行う方法はありますか?


編集 22.10.2010

だからみんな、ベクトルをデバッグした後、私はこの解決策を思いつきました:

vector<char> dump;
memcpy(&myVector, &dump, sizeof(myVector)); // I change contents so it can work
myVector.assign(buf, buf+5); // copy contents into it from buffer (I don't like this part)

そして、これを機能させるには、定義する必要がありました

_ITERATOR_DEBUG_LEVEL=0

最初は 2 に設定されていて、実際にデバッグ チェックを行っているためです (推測します)。これはリリース モードでも定義されていません。今のところ私の回避策です。長期的には ppl にベクトルを強制的に削除させたいと思います...では、この解決策についてどう思いますか? そして、あなたが見る危険はありますか?


実際には memcpy でベクターをシリアライズする必要があります。クラス全体をシリアル化し(メモリのスナップショットを取得するなど)、ファイルに書き込み、リロード時にファイルから読み取り、コンストラクターを呼び出して新しい演算子を使用せずにオブジェクトを復元したい。

うーん、このベクター コンテナーはスタック メモリ上で実行されているため、memcpy はそれに到達できません。ヒープだけが問題なので、このコードは今のところうまくいくかもしれません。

copy(buf, buf + 5 myVvector.begin());

クラスで new キーワードを使用していないため、これも機能していません。私が理解している限り、このベクトルは初期化されていません。したがって、コピーしようとすると、このベクターを smt で push_back_fill すると、次のエラーが表示されます。

newDel.exe の 0x00ec455b で未処理の例外: 0xC0000005: アクセス違反の読み取り場所 0x00654b4c.

これは理にかなっています...だから、ベクトルのコンストラクター/イニシャライザーを外部から呼び出す方法を知っている人はいますか?

4

6 に答える 6

4

あなたが持っていた場合

vector<char> foo;

foo.push_back( 'v' );
foo.push_back( 'e' );
foo.push_back( 'c' );
foo.push_back( 't' );
foo.push_back( 'o' );
foo.push_back( 'r' );

char *c = &foo[0];

これにより、ベクトルのコンテンツの最初の項目へのポインタが作成されます。これは、ベクトルのサイズを変更しようとするまで有効です。

編集:

あなたはこの方法であなたが望むことをすることができます:

copy( c, c+6, back_inserter( myVector ) );

これは、からのcopy呼び出しとからalgorithmback_inserter関数呼び出しですiterator

于 2010-10-21T14:36:52.873 に答える
3

それを行うための標準的な方法はありません。特定の実装を掘り下げて、それを処理する方法を確認することはできますが(実際には方法がない場合もあります)、ライブラリが変更または更新された場合、トリックが失敗する可能性があります。ライブラリの作成者は通常、そのような使用をサポートする必要性を感じていません。

vector<>コンテナクラスです。これはCスタイルの配列のラッパーではありませんが、内部で保持しています。その動作とパフォーマンスは標準で指定されていますが、内部では指定されていません(ただし、その内容は連続したメモリに保存する必要があります)。ライブラリの作成者は、その自由を利用して、可能な限り最高の実装を作成します。

内部ポインタに割り当てることができると仮定します。これは間違いなくフリーストアからのメモリを指していますが、メモリの先頭、newまたはからの戻り値を指していない可能性がありmalloc()ます。メモリのサイズは、容量に要素のサイズを掛けたものを保持するのに少なくとも十分でなければなりませんが、実際にはそれより大きくなる場合があります。は、そのvector<>コンテンツが特定のプールの一部であるか、特定の方法で割り当ておよび割り当て解除されることに依存している可能性があります。vector<>割り当ては、おそらくへのポインタなど、の他のデータメンバーに影響を与える可能性があります.end()。これらのいずれの場合でも、正確な実装を知らなければ、メモリと変数を自分で管理することはできません。

一般に、実装の内部をいじるのはエラーが発生しやすく、ライブラリに変更を加えると、すぐに明らかな影響がある場合とない場合で、破損する可能性があります。また、それはしばしば必要ではなく、望ましいことさえありません。ベクトルをシリアル化する別の方法を見つけます。

于 2010-10-21T14:59:38.887 に答える
0

それが「内部」である場合は、改ざんされないようにプロバルビーを使用してください。

于 2010-10-21T14:37:34.477 に答える
0

これはあなたの役に立ちますか?

vector<char*> v;
char* c = { 'v', 'e', 'c', 't', 'o', 'r' };  
v.push_back(c);
于 2010-10-21T15:29:51.387 に答える
0

I/O バッファーに別のベクターを使用する場合はstd::swap、コンテンツを変更するために使用できます (ポインターと、カウントが格納されている場所など、他の適切なデータが更新されます)。

于 2010-10-21T15:38:57.983 に答える
0

私はあなた自身の答えを見ました(ところで、答えとして投稿すべきではありません。質問に編集されているはずです)。したがって、C++ でシリアル化を行いたいとします。memcpy をあきらめて、boost::serialization などの適切なシリアル化機能を使用してください。それはいいことではありませんが、必要です。そうしないと、単に機能しません。C++ はそのようには機能しません。

于 2010-10-21T16:16:57.517 に答える