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

发布于 2024-12-13 06:14:43 字数 536 浏览 5 评论 0原文

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

示例代码)

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 库。

谢谢!

I fear that I am running into memory leak issues by doing the following:

(Sample code)

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 doesn't free the memory if it's a pointer, right? If I wasn't using remove_if, I could call delete on the pointer before destroying it. How would I do it in this case? Smart Pointers? I'd prefer not to re-implement everything with them and I don't really want to add the boost library.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

兔小萌 2024-12-20 06:14:43

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

You could just delete the item in your IsMarkedToDelete function when it returns true.

╰ゝ天使的微笑 2024-12-20 06:14:43

如果指向该对象的唯一指针位于向量中,那么您已经
一旦调用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;这
将确保最终从向量中删除的任何指针
将被删除。如果做不到这一点,您可以使用两次通过:第一次
是一个 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() );

If the only pointers to the object were in the vector, then you've
leaked memory as soon as you call remove_if. remove_if moves the
pointers which you are keeping down, but it doesn't say anything about
the values behind the iterator it returns. Thus if you have something
like [a, b, c, d] (where a, b, etc. represent different pointers),
then after e = remove_if( v.begin(), v.end(), matches(b) ), your
vector might (and probably will) look like [a, c, d, d], with e
pointing to the second d, and all trace of b lost forever.

The obvious solution would be to use shared_ptr in the vector; this
would ensure that any pointer which ended up removed from the vector
would be deleted. Failing that, you can use two passes: the first would
be a for_each with something like:

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() );

as the functional object, followed by:

v.erase( std::remove( v.begin(), v.end(), NULL ), v.end() );
心舞飞扬 2024-12-20 06:14:43

您可以使用此功能:

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

You can use this function:

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());
}

Ex:

delete_if(MyVec, [](T* item) { return item->index == 5; });
小ぇ时光︴ 2024-12-20 06:14:43

您可以使用remove_if,然后使用for_each从返回值开始直到末尾,然后擦除。当然,这会让你的代码变得更长一些。另一种可能性是存储 shared_ptr 指针,如果您的代码同意的话。

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

You can use remove_if, then for_each from the return value till the end and then erase. That would, of course, make your code a bit longer. Another possibility is to store shared_ptr pointers, if your code agrees with that.

The above is a blunt lie, as Benjamin pointed out, so you're only left with "another possibility".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文