使用 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
会有所帮助...
我有这个函数,它的作用是删除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
会有所帮助...