使用 std::vector 中的擦除功能

using the function erase in std::vector

我有这个函数,它的作用是删除classBaseFile的一个指针 来自一个名为 children

的向量
 //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
            }
        } 
    }
}

第一个问题是为什么我在行中收到错误 (delete a;)? 擦除方法删除指针并删除它? 如果是的话,我怎样才能从矢量中删除指针而不删除它在 Heap/Stack 中的内容?

你需要做的是使用std::remove_if获取没有匹配元素的向量。

但是,一旦您执行了对 std::remove_if 的调用,您就无法 delete 匹配项,如 documentation 状态(强调我的):

Removing is done by shifting (by means of move assignment) the elements in the range in such a way that the elements that are not to be removed appear in the beginning of the range. Relative order of the elements that remain is preserved and the physical size of the container is unchanged. Iterators pointing to an element between the new logical end and the physical end of the range are still dereferenceable, but the elements themselves have unspecified values (as per MoveAssignable post-condition).

因此我们将直接在谓词中处理删除。请注意,我们还必须注意不要重复释放任何内容,因此我们将通过使用 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));
}

最后,我希望您作为 file 参数给出的指针也不是 children 的成员,如果是,您也不会以 delete-ing 它!

注意:在你的情况下不能使用智能指针吗? Directory 对象似乎对存储在 children 中的 BaseFile 对象拥有所有权...所以也许 std::unique_ptr 会有所帮助...