2017-10-11 16 views
-3

私はC++を学んでいますが、今はイテレータに問題があります。これは私の場合です:私はここにこのコードを持っています。リストのセグメンテーションフォールト<Object*>イテレータ

// std::list<Dragon*> dragons = cave.getDragons(); 
for (std::list<Dragon*>::iterator it = cave.getDragons().begin(); it != cave.getDragons().end(); it++){ 
     os << std::endl << (*it)->getName(); 
} 

セグメンテーションフォールトを返します。これは私のリストと私のgetDragons()メソッドです:

std::list<Dragon*> dragons; 
std::list<Dragon*> getDragons() const {return dragons;} 

そして、私の質問は...私はこのようなことをやってセグメンテーションフォールトを持っていないのはなぜ、私はコメントしている、変数ドラゴンを使用する場合は、ドン」 t?ありがとう!

+2

あなたは 'Dragon *'のリストを持っていて、それの先頭までイテレータを作成してから、リストを削除して破棄させます。次に、イテレータと同様の破壊リストと比較します。いずれにせよ、範囲ベースのforループを使用してください(foreachループ: 'for(auto * dragon:cave.getDragons())) – Justin

+0

' getDragons() 'はコピーを返します。多分あなたは参照をしたいですか? –

+0

ありテスターはだし、それは、このコードで動作するように持っている: 'オートそれ= cave-> getDragons())(始まる;それはないテスター –

答えて

1

getDragons()はそうあなたがgetDragons()を呼び出すたびに、あなたがdragonsリストのコピーを取得し、値によってstd::listを返します。したがって、forループは異なる一時的なstd::listオブジェクトの反復子を比較しており、無効な反復子を逆参照しようとしています。

std::list<Dragon*> dragons = cave.getDragons(); 
for (std::list<Dragon*>::iterator it = dragons.begin(); it != dragons.end(); it++){ 
    os << std::endl << (*it)->getName(); 
} 

それとも、あなたがC++ 11以降を使用している場合は、代わりにfor-rangeループを使用します:

for (Dragon *dragon : cave.getDragons()) { 
    os << std::endl << dragon->getName(); 
} 

そうでなければ、あなたはより多くの代わりにこのような何かをする必要があり

代わりに、参照することによりstd::listを返すようにgetDragons()を変更する必要があります。

const std::list<Dragon*>& getDragons() const {return dragons;} 

その後、オリジナルのforコードは機能しますが、それでもループの繰り返しごとにgetDragons()が呼び出されます。

const std::list<Dragon*> &dragons = cave.getDragons(); 
for (std::list<Dragon*>::const_iterator it = dragons.begin(); it != dragons.end(); it++){ 
    os << std::endl << (*it)->getName(); 
} 

あるいは、上記のように同じC++ 11 for-rangeループを使用します。これは、ローカル変数への単一の呼び出しの結果をキャッシュするのが最善です。

0

あなたの根底にあるエラーは、レミーの説明のように、リストのコピーの使用です(エラーが発生しやすくなるだけでなく非効率的でもあります)。したがって、正しい治療法はになりません。はそのようなコピーを作成します(Remyの答えは依然としてそうすることを提案しています)。この目的のために、getDragons()メソッドは参照を返す必要があります。

struct Cave 
{ 
    /* ... */ 
    std::list<const Dragon*> const&getDragons() const; 
}; 

また、あなたは可能な限りautoキーワードを使用します(もちろん、少なくとも2011標準を使用する)必要があります。

for(auto const&dragon : cave.getDragons()) 
    os << std::endl << dragon.getName(); 
関連する問題