2009-07-16 10 views
4

私は別のアプリケーションが使用するDLLを構築しています。私はいくつかのデータの現在の状態をDLLのメモリに関数呼び出しから返す前にグローバルに保存して、関数の次の呼び出し時に状態を再利用できるようにしたい。コンテナ内にイテレータを格納する

これを行うには、いくつかのイテレータを保存する必要があります。他のすべてのデータを格納するためにstd :: stackを使用していますが、イテレータでもできるかどうかはわかりませんでした。

コンテナクラスの中にリストイテレータを置くことは安全ですか?そうでない場合は、後で使用できるようにリスト内の要素へのポインタを格納する方法を提案できますか?

リストの代わりに私のデータを格納するベクトルを使って、私が下付き文字を格納し、それを非常に簡単に再利用できるようになったと知っていますが、残念ながらstd :: listのみを使用する必要があります。

答えて

5

はい、うまくいきます。

これはリストイテレータの特別な品質であることを他の多くの回答が話しているので、イテレータ(ベクトルを含む)で動作することを指摘しておきます。ベクトルが変更された場合、ベクトル反復子が無効になるという事実は、反復子を別のコンテナに格納することが合法かどうかという問題にはほとんど関係ありません。です。もちろん、イテレータは、無効化する処理を行うと無効になることがありますが、イテレータがスタック(または他のデータ構造)に格納されているかどうかは関係ありません。

5

イテレータを格納するには問題ありません。リストのコピーでイテレータを使用しないでください。イテレータはリストの1つのインスタンスにバインドされ、コピーでは使用できません。

std::list<int>::iterator it = myList.begin(); 
std::list<int> c = myList; 

c.insert (it, ...); // Error 

他の人が指摘したように:あなたがしなければ、ある

もちろん、あなたはまた、尖った-の要素を除去することにより、イテレータを無効にはなりません。

0

同じルールは、ローカルの変数に格納されているイテレータに、より長生きのデータ構造と同様に適用されます。コンテナが許す限り有効です。

リストの場合、これは、ポイントするノードが削除されていない限り、イテレーターは有効のままです。リストが破壊されたときにノードが削除されることは明らかである...

6

リストにはイテレータが無効になっているか、リスト内の "pointed"要素が削除されている場合にのみ無効になる。

1

リストのイテレータを格納するのは問題ありません。イテレータを格納しているリストから同じ要素を削除しない限り無効になりません。 SGIサイトから以下の引用:

リスト 挿入やスプライシングが、要素をリストするイテレータを無効 も除去が削除され 要素を指し示すだけ イテレータを無効にすることはない ないという重要な特性を持っています

ただし、格納されているイテレータの前後の要素が変更される可能性があることに注意してください。しかし、反復子自体は有効なままです。

+0

彼はリストを変更については何も言わなかったので、私は無効化が最初の場所で問題になる可能性がどのように見ることができません。 – jalf

-1

はい。リストは行く方法です。あなたは私の答えをここで同様の質問に参照することができます: What is the lifetime and validity of C++ iterators:

+0

リストだけでなく、どのイテレータでも動作します。質問はリストを変更することについて何も言わないので、生涯または妥当性は実際には関係ありません。 – jalf

2

これはofftopicかもしれませんが、ちょうどヒント...

は、あなたの関数(S)/データ構造は、おそらく読み取り操作でスレッド安全ではないことがあろうと、注意してください。読み取り操作で同期が必要ない基本的なスレッドセーフティがあります。呼び出し元が構造体からどれくらい読み込んだかを保存する場合は、コンセプトスレッド全体が安全でなく、使い方が少し不自然になります。なぜなら、誰も読取りを状態の完全な操作と見なすからです。

2つのスレッドが呼び出す場合は、呼び出しを同期する必要があります。そうしないと、競合状態でデータ構造が終了する可能性があります。このような設計の問題は、両方のスレッドが共通の同期変数にアクセスできる必要があることです。

私は、2つのオーバーロードされた機能を作成することをお勧めします。両方ともステートレスですが、そのうちの1つは、次の読み込み/検索/取得などを開始するためのヒントイテレータを受け入れる必要があります。 STLのAllocatorがどのように実装されているか。新しいメモリチャンクをすばやく見つけるために、ヒントポインタ(デフォルトは0)をアロケータに渡すことができます。

よろしく、
Ovanes

+0

ヒント、オヴァーンありがとう。しかし、各スレッドの状態が別の場所に格納されているため、私の場合は問題は発生しません。一度に1つのスレッドだけがコンテナから読み込みます。私はオーバーロードされた関数の仕方を完全に理解しているかどうか分からないが、私はAllocatorsについて読む必要があるだろうが、提案にも感謝する。それは面白そう – Sahas