1

リストを最初にベクターにコピーしてから空のリストに戻すことで、リストをシャッフルしようとしています。

vector<Agent*> tmpVector(agents_.size());
copy(agents_.begin(), agents_.end(), tmpVector.begin());
random_shuffle(tmpVector.begin(), tmpVector.end());
agents_.clear();
copy(tmpVector.begin(), tmpVector.end(),agents_.begin());

プログラムが実行時エラーでクラッシュします:リストイテレータは参照解除できません

1-コードの何が問題になっていますか。

2-リストにはポインタが含まれています。上記のアプローチが機能する場合は何も問題がないと思います(ポインタ値は変更されず、割り当てられた変数は後でそれらを参照できるため)、そうですか?

ありがとう。

4

3 に答える 3

2

問題は次の2行にあると思います。

agents_.clear();
copy(tmpVector.begin(), tmpVector.end(),agents_.begin());

この最初の行はリストをクリアするagents_ので、空になります。次に、次の行はagents_、最初の要素から始まるに格納されている要素のシーケンスを範囲の内容に置き換えようとします[tmpVector.begin(), tmpVector.end())。リストに要素がないため、これにより未定義の動作が発生します。

これを修正するにagents_.clear()は、前の行からへの呼び出しを削除してみてください。これにより、copy呼び出しはリスト内の既存の要素をagents_適切にシャッフルされた値で上書きします。

お役に立てれば!

于 2013-03-25T04:50:02.273 に答える
1

tmp配列をclear()するときは、そのサイズをゼロに設定します。

コピーは、宛先に十分なスペースがすでに設定されていることを想定しています(つまり、サイズが正しい必要があります)。

最初の選択肢は、バックインサーターを使用することです。

agents_.clear();
std::copy(tmpVector.begin(), tmpVector.end(), std::back_inserter(agents_));

しかし、宛先でポインターを使用しているためです。
それらを問​​題なくコピーします。したがって、クリアを削除する方がおそらく簡単です。

// agents_.clear();
// The copy will copy over the old values with no problems.
copy(tmpVector.begin(), tmpVector.end(),agents_.begin());
于 2013-03-25T04:51:44.577 に答える
1

問題は最後の2行から来ています:

agents_.clear();
copy(tmpVector.begin(), tmpVector.end(),agents_.begin());

具体的にはclear()、リストを呼び出します。これにより、すべての要素が破棄され、サイズが0のままになり、にアクセスしようとしますbegin()。逆参照しようとするとbegin()、未定義の動作に変わります。

このコードはかなりクリーンアップできます。

vector<Agent*> tmpVector(agents_.begin(), agents_.end());
random_shuffle(tmpVector.begin(), tmpVector.end());
copy(tmpVector.begin(), tmpVector.end(),agents_.begin());

あなたがやりたいことをします。1つ目copyは不要で、vectorこの場合に使用できる2つのイテレーターを使用するコンストラクターがあります。

于 2013-03-25T04:57:20.273 に答える