2017-01-28 9 views
0

私はこのコードの一部を試みたとき:C++セットのバグ?

int x=*(s.rbegin()); 
while(!s.empty()&&0<x) 
{ 
    s.erase(x); 
    x=*(s.rbegin()); 
} 

私は消去を呼び出すとき、それは実際には何も消去されませんので、それは無限ループに実行されます。 *(s.rbegin())は間違いなくsに入るはずですから、これは変です。

+1

xの値は? –

+4

セットの最後の値が消去された後、定義されていない動作が発生し、そのイテレータから参照を逆参照します。セットが空になる前に '0

+0

どのように 's'を宣言しましたか? –

答えて

-1

あなたはたとえば..あなたは、あなたが取得したい要素を削除し、アクションのx=*(s.rbegin());

int x=*(s.rbegin()); 
while(!s.empty() && 0<x) 
{ 
    s.erase(x); 
    if(!s.empty()) 
     x=*(s.rbegin()); 
} 
+0

ループ内の 'rbegin()'だけでなく、ループに入る前の最初の 'rbegin()'にも適用される "*の終わりをチェックする" * –

0

変更オーダーの前にセットの終了を確認する必要があります:

std::set<int> s; 

int x; 
s.insert(5); 
s.insert(15); 
s.insert(25); 
s.insert(0); 
s.insert(20); 
while(!s.empty()&& (0<(x=*s.rbegin()))) 
{ 
    std::cout<< x << "\n"; 
    s.erase(x); 
} 

が道であることに注意してくださいあなたは定義している間。上記のコードの出力は

25 
20 
15 
5 

が邪魔にあなたはそれが0の要素が見つかった場合に停止することを意図しながら、()ループを定義していることに注意してくださいになります。終了後に0が残っています。セットは空ではありません。あなたがすべての要素を消去しようとしているようだ

std::set<int>::reverse_iterator iter = s.rbegin(); 
while ((iter != s.rend()) && ((0 < *iter)) 
    s.erase((iter++).base()); 
0

のように見えますセット内ではポジティブです。これは、この一行をずっと簡単に行うことができます。最後までこの1からすべての要素は、あなたができる、ゼロよりも大きいことが保証されているので

s.erase(s.upper_bound(0),s.end()); 

upper_boundは0より大きい最初の番号にあなたのイテレータを提供しますそれらをすべて消去します。

+0

std :: remove_ifは動作しませんstd :: setを使用すると、読み込み専用ロケーションエラーの割り当てを取得します。最後のコンパイラは、vc6(STLの珍しい実装のため)でした。 – Swift

+0

@Swift Thanks、回答。 –

0

また
if (!s.empty()) 
{ 
    int x = *(s.rbegin()); 
    while (0 < x) 
    { 
     s.erase(x); 
     if (s.empty()) break; 
     x = *(s.rbegin()); 
    } 
} 

を、代わりに値のイテレータを使用して消去してみてください:伝統的に使用反復は代わりにこれを試してみてください

for (auto it=s.rbegin(); it!=s.rend(); ++it) 
{ 
}