c++ - 使用 std::vector 中的删除函数

标签 c++ pointers vector erase

我有这个函数,它的目的是删除BaseFile类的指针 来自一个名为“children”的 vector

 //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;) 中收到错误? 删除方法是否会删除指针并删除它? 如果是,我如何从 vector 中删除指针而不删除它在堆/堆栈中的内容?

最佳答案

您需要做的是使用 std::remove_if获取没有匹配元素的 vector 。

但是,一旦您执行了对 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对象拥有 BaseFile 的所有权存储在 children 中的对象...所以也许std::unique_ptr会有所帮助...

关于c++ - 使用 std::vector 中的删除函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47279233/

相关文章:

c - 数组指针的类型是什么?

c++ - 为什么使用本地指针不起作用

c++ - 生成给定集合的子集

c++ - 将字母转换为整数,然后求字符串之和

C++ 静态虚拟成员?

java - 术语:如何谈论 Java 中的指针和引用

c++ - 对 map 中的 vector 进行排序

c++ - vector<wstring> 作为返回值和参数

c++ - C++ 中哪些类型被认为是可调用的?

c++ - 我在哪里可以找到 gtk+ (c++) 类型问题的主要论坛?