关于remove_if的错误用法

前天收到一个工作中的Bug,仔细查了一下,发现是自已对stl某算法理解的一个大错误。
问题如下:
一:背景:
         我有一个vector容器,基本单元很特珠,需要在丢弃前释放其内部的一个指针成员。
         (这可能是我的设计不合理造成的,有些怪)
         如: vector<C_UIAction>  m_lstUIAction;
                   C_UIAction ::m_pAttach 在不用时手工需要释放,析构时不释放。
二:我现在需要过滤掉某些元素。
        于是:我写了个Functor,然后用remove_if来进行过滤。
       vector<C_UIAction>::iterator new_end =
              remove_if(m_lstUIAction.begin(),m_lstUIAction.end(),Func_remove_predicate());
         为了保证Func_remove_predicate()的通用性,我决定不在Functor内部进行
内存释放。而是在这个步骤后,实际删除前手工释放。

三:于是:释放内存
for(it=new_end;it!= m_lstUIAction.end();it++)
              M_SAFEDELETE it->m_pAttach

四最后:删除元素       
m_lstUIAction.erase(new_end,m_lstUIAction.end());

好了,上述做法,看似没问题,但实际上第三步会有大问题。也就是说第三步中期望的释放是不正常的。
更进一步说(我跟踪了一下,迭代器的指向是不正确,并不是希望被过滤掉的元素指向)

查查STL的标准说法:
调用remove_if后得到的 [new_end,last] 内的所有iterators仍然可以提领,
但其指向之值未在规范之列(unspecified)。

结论:
1:使用算法remove_if后,对于VC的STL实现,不保证new_end到last间的迭代器指向正确。
一般情况下,是肯定不正确的。因此,不要依赖其指向做其它操作。
正常做法:remove_if后直接调用容器的erase来去除元素,中间就不要做任何事了。

2:对于STL的使用,因为有多种实现,所以必须注意看STL标准的特别声明,不能想当然的使用。
因为,很有可能不同实现会有区别,只能依赖于规范,其它需要实验。(实际上VC6的STL实现是很
差的,连规范都没达到)

3:对于我的特殊需求,只能是在functor里进行内存释放,当然,此functor属于专用配套使用了。
如:
       bool operator() (C_UIAction x)
       {
              if(x.m_bFinish) M_SAFEDELETE(x.m_pAttach);
              return x.m_bFinish;
       }

你可能感兴趣的:(c,算法,工作,vector,iterator,functor)