次の方法で消去を使用してマップから要素を削除していますが、正しく機能していません。なんで?すべてを削除するわけではありません。
float nw_cut=80.0;
for(it=nw_tot1.begin();it!=nw_tot1.end();it++)
{
float f=(float) ((float) it->second/lines)*100.0;
if ( f < nw_cut )
{
nw_tot1.erase(it);
}
}
消去された要素への参照と反復子は無効になります。他の参照と反復子は影響を受けません。
erase(it)
が呼び出された場合はit
無効になり、for
ループによって使用され、未定義の動作が発生します。の戻り値を格納しerase()
ます。これは、消去された要素の次の要素への反復子を返します (c++11 以降)。erase()
呼び出されなかった場合にのみインクリメントします。
for(it = nw_tot1.begin(); it != nw_tot1.end();)
{
float f=(float) ((float) it->second/lines)*100.0;
if ( f < nw_cut ) it = nw_tot1.erase(it);
else ++it;
}
c++03 (および c++11 も) では、これは次の方法で実現できます。
for(it = nw_tot1.begin(); it != nw_tot1.end();)
{
float f=(float) ((float) it->second/lines)*100.0;
if ( f < nw_cut ) nw_tot1.erase(it++);
else ++it;
}
次のようにする必要があります。
float nw_cut=80.0;
for(it=nw_tot1.begin();it!=nw_tot1.end();)
{
float f=(float) ((float) it->second/lines)*100.0;
it_temp = it; //store it in temp variable because reference is invalidated when you use it in erase.
++it;
if ( f < nw_cut ) {
nw_tot1.erase(it_temp);
}
}
for(it = nw_tot1.begin(); it != nw_tot1.end();)
{
float f=(float) ((float) it->second/lines)*100.0;
if ( f < nw_cut ) it = nw_tot1.erase(it);
else ++it;
}