如果使用remove_if,并且项是指向对象的指针,如何删除vector中的项?

How do delete items in a vector if using remove_if and items are pointers to objects?

本文关键字:何删除 指针 删除 vector remove if 如果 对象      更新时间:2023-10-16

我担心通过执行以下操作会遇到内存泄漏问题:

(示例代码)
class myItem //random container stuff mostly. All primatives.
{
    int index;
    char* name;
    int val1;
    int val2;
};
class vecList
{
    vector< myitem* > *myVec;
    void delete()
    { 
        MyVec->erase(std::remove_if(myVec->begin(), MyVec->end(), IsMarkedToDelete), MyVec->end()); //leak here?
    }
};

Erase不释放内存,如果它是指针,对吗?如果我没有使用remove_if,我可以在销毁指针之前对它调用delete。在这种情况下我该怎么做呢?智能指针?我不喜欢用它们重新实现所有东西,我真的不想添加boost库。

谢谢!

您可以在IsMarkedToDelete函数返回true时删除该项。

如果指向该对象的指针都在vector容器中,那么就没有对象一旦调用remove_if就会泄漏内存。remove_if移动指针,你把它记下来,但它什么也没说它返回的迭代器背后的值。因此,如果你有什么比如[a, b, c, d](其中ab等代表不同的指针),然后在e = remove_if( v.begin(), v.end(), matches(b) )之后,你的向量可能(也可能)看起来像[a, c, d, d]e指向第二个d, b的所有踪迹将永远消失。

显而易见的解决方案是在vector中使用shared_ptr;这将确保任何指针最终从vector中删除将被删除。如果做不到这一点,你可以使用两种方法:第一种方法在for_each中添加如下内容:

struct DeleteIfCondition
{
    void operator()( ObjectType* &ptr ) const
    {
        if ( condition( *ptr ) ) {
            ObjectType* tmp = ptr;
            ptr = NULL;
            delete tmp;
        }
    }
};
std::for_each( v.begin(), v.end(), DeleteIfCondition() );

作为功能对象,后面接:

v.erase( std::remove( v.begin(), v.end(), NULL ), v.end() );

您可以使用remove_if,然后使用for_each从返回值直到结束,然后擦除。当然,这将使您的代码更长一些。另一种可能是存储shared_ptr指针,如果你的代码同意的话。

以上是一个直言不讳的谎言,正如Benjamin指出的那样,所以你只剩下"另一种可能性"。

你可以使用这个函数:

template<typename T, typename TESTFN>
void delete_if(std::vector<T*>& vec, TESTFN&& predicate)
{
   auto it = remove_if(vec.begin(), vec.end(), [&](T* item) {
      if (predicate(item)) {
         delete item;
         return true;
      }
      return false;
   });
   vec.erase(it, vec.end());
}

,

delete_if(MyVec, [](T* item) { return item->index == 5; });