1

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

(示例代码)

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?
    }
};

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

谢谢!

4

4 回答 4

9

IsMarkedToDelete当它返回 true 时,您可以删除函数中的项目。

于 2011-11-01T14:49:04.983 回答
3

如果指向该对象的唯一指针在向量中,那么您在调用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永远丢失。

显而易见的解决方案是shared_ptrvector; 这将确保最终从 中删除的任何指针都vector 将被删除。如果做不到这一点,您可以使用两次通行证:第一个将是 afor_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() );
于 2011-11-01T14:55:27.513 回答
1

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

正如本杰明指出的那样,以上是一个直率的谎言,所以你只剩下“另一种可能性”。

于 2011-11-01T14:35:40.117 回答
0

您可以使用此功能:

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; });
于 2021-05-27T14:10:41.140 回答