1

メソッドと数値プロパティActionを持つクラスにしましょう。しましょうis_finishedtagthis->vactionsstd::vector<Action>

その目的は、ベクトルを反復し、終了したアクションを特定し、それらのタグを に保存してstd::vector<unsigned int>、アクションを削除することです。

私はラムダと少し遊んでみましたが、うまく読めるがメモリの破損を引き起こす小さなコードを思いつきました。一方、「拡張」バージョンは期待どおりに機能します。

remove_if の部分で不正行為が疑われますが、私の人生では、何が問題なのかわかりません。

これがサンプルコードです。

これにより、メモリが破損します

std::vector<unsigned int> tags;

auto is_finished=[p_delta](Action& action) -> bool  {return action.is_finished();};

//This is supposed to put the finished actions at the end of the vector and return
//a iterator to the first element that is finished.
std::vector<Action>::iterator nend=remove_if(this->vactions.begin(), this->vactions.end(), is_finished);

auto store_tag=[&tags](Action& action)
{
    if(action->has_tag()) 
    {
        tags.push_back(action->get_tag());  
    }
};

//Store the tags...
for_each(nend, this->vactions.end(), store_tag);

//Erase the finished ones, they're supposed to be at the end.
this->vaction.erase(nend, this->vaction.end());

if(tags.size())
{
    auto do_something=[this](unsigned int tag){this->do_something_with_tag(tag);};
    for_each(tags.begin(), tags.end(), do_something);
}   

一方、これは期待どおりに機能します

std::vector<Action>::iterator   ini=this->vactions.begin(),
                end=this->vactions.end();

std::vector<unsigned int> tags;

while(ini < end)
{
    if( (*ini).is_finished())
    {
        if((*ini).has_tag())
        {
            tags.push_back((*ini).get_tag());
        }

        ini=this->vaction.erase(ini);
        end=this->vaction.end();
    }
    else
    {
        ++ini;
    }
}

if(tags.size())
{
    auto do_something=[this](unsigned int tag){this->do_something_with_tag(tag);};
    for_each(tags.begin(), tags.end(), do_something);
}   

ここには初歩的なミスがあると確信しています。それを見つけるのを手伝ってもらえますか?.

for_eachがイテレータを更新している可能性があると思いましたnendが、それに関する情報は見つかりませんでした。もしそうなら?ベクトルは「終点」を超えて消去しようとする可能性がありますか?.

4

1 に答える 1

3

std::remove_if削除される要素の値は保持されません ( cppreferenceを参照)。remove_if2 番目のケースのように、呼び出す前にタグの値を取得するか、std::partition代わりに使用します。

于 2013-06-27T22:09:09.527 に答える