2017-11-14 21 views
2

私はこの機能を持っているを使用して、その目的は、私はエラーを取得していますなぜSTD関数消去::ベクトル

//children is vector of type vector<BaseFile*> 
void Directory::removeFile(BaseFile* file) 
{ 
    for(int i = 0 ; (unsigned)i < children.size() ; i++) 
    { 
     if ((children[i]->getName()).compare(file->getName()) == 0) 
     {  
      BaseFile* a = children[i]; 
      children.erase(children.begin()+i); 
      if(a != nullptr) 
      { 
       delete a;//err in this line : double free or corruption 
      } 
     } 
    } 
} 

最初の質問は、子供と呼ばれるベクトルからクラスBASEFILE のポインタを削除することです行(削除a;)? 用量を消去すると、それを削除するポインタが削除されますか? もしそうなら、私はどのようにHeap/Stackの中のコンテンツを削除せずにベクトルからポインタを削除できますか?

+1

cppreferenceの[のstd ::ベクトルページの「メンバ関数」セクションを参照してください。 com](http://en.cppreference.com/w/cpp/container/vector)。あなたが何か他のものが必要なのかどうか私たちにお知らせください。 – Drop

+1

1回の繰り返しで複数のアイテムを消去したい場合、このコードには欠陥があります。残りの人は確かにドキュメントを読んでください – Laurijssen

+0

私は私に何をするように頼まれたのか分かりません!!! –

答えて

2

対応する要素のないベクトルを取得するには、std::remove_ifを使用します。

の削除(移動の割り当てによって)シフトすることにより行われません:あなたは、あなたが持っているstd::remove_ifへの呼び出しを行った後しかし、documentation状態(強調鉱山)などdelete一致する項目への道が

範囲内の要素は、削除されない要素が範囲の先頭に表示されるようにします。残っている要素の相対的な順序は保持され、コンテナの物理的なサイズは変更されません。 新しい論理終わりとその範囲の物理終端の間の要素を指すイテレータは、まだ逆参照可能ですが、要素自体には未指定の値があります(MoveAssignable後の条件に従って)

したがって、削除を直接述語で処理します。我々はまた、無料のものを倍増しないように注意する必要がありますので、私たちは最後に、私はあなたがfile引数ISN」として与えるそのポインタを願っていstd::unordered_set

void Directory::removeFile(BaseFile *file) { 
    std::unordered_set<BaseFile*> deleted_set { file }; // Just to avoid deleting the input argument if it's stored in children as well... 
    auto match_it = std::remove_if(begin(children), end(children), 
      [&](BaseFile *current_file) -> bool { 
       bool result = current_file->getName().compare(file->getName()) == 0; 
       if (result && end(deleted_set) == deleted_set.find(current_file)) { 
        delete current_file; 
        deleted_set.insert(current_file); 
       } 
       return result; 
      }); 
    children.erase(match_it, end(children)); 
} 

を使用して削除されたアイテムを追跡しますchildrenのメンバーでもありますが、そうであれば、あなたはdeleteになりません。

注:スマートポインタを使用することはできませんか? Directoryオブジェクトがchildrenに保存されているBaseFileオブジェクトの所有権を持っているようだ...だから多分std::unique_ptrが役立つだろう...

+0

forループにいくつかの質問が残っていますあなたのコードでは(私はそれに感謝しています)(*)それを指すポインタです。私の新しいベクトルの終わり、私が削除したくない要素(it = match_it +1) –

+0

@BaraaNatour '++ it'または' it ++ 'は本当に問題ではありませんが前者(https://stackoverflow.com/a/38948073/1794345を参照)を使用してパフォーマンスを向上させてください。 – Rerito

+0

@BaraaNatour私は、ドキュメントに従って 'remove_if'を使用した後に要素を削除できないことに気付きました。私の答えを訂正する時間を与えてください – Rerito

関連する問題