我有这个函数,它的目的是删除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/