我担心通过执行以下操作会遇到内存泄漏问题:
(示例代码)
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库。
谢谢!
答案 0 :(得分:8)
您可以在IsMarkedToDelete
函数返回true时删除该项。
答案 1 :(得分:3)
如果对象的唯一指针在向量中,那么你就是
一旦拨打remove_if
,就会泄露内存。 remove_if
移动了
你要记下的指针,但它没有说什么
它返回的迭代器后面的值。因此,如果你有东西
例如[a, b, c, d]
(其中a
,b
等表示不同的指针),
然后在e = remove_if( v.begin(), v.end(), matches(b) )
之后,你的
矢量可能(也可能会)看起来像[a, c, d, d]
,e
指向第二个d
,b
的所有痕迹都永远丢失。
显而易见的解决方案是在shared_ptr
中使用vector
;这个
将确保最终从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() );
答案 2 :(得分:1)
您可以使用remove_if
,然后从返回值使用for_each
直到结束,然后删除。当然,这会使你的代码更长一些。另一种可能性是存储shared_ptr
指针,如果您的代码与此一致。
正如本杰明指出的那样,上面是一个直言不讳的谎言,所以你只剩下“另一种可能性”。
答案 3 :(得分: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; });