STL Vector 的遍历删除

转载自:http://www.cppblog.com/Khan/archive/2009/12/08/102793.html

Vector 其实就类似动态数组. 事先分配好一定量的内存. 当需要的内存值大于某个阀值. 就重新申请内存. 重新分配. 当小于某个阀值, 也会导致重新分配.(自动收缩部分, stl没有明确规定, 有些库实现了)

正确: code1
      vector<string> vecFiles;
      vector<string>::iterator  it_pos;
      //@todo 已下载文件过滤
      for (it_pos = vecFiles.begin(); it_pos != vecFiles.end(); ) { 
        string strTmp = *it_pos;
        if( objDownHis.checkHisList( strTmp.c_str() ) ){ //判断是否已下载过, 已下载则从列表删除
          g_Log << TIME << "file:[" << *it_pos << "] found "<< END; //
          vecFiles.erase(it_pos++);
        }else 
          it_pos++;
      }


正确: code2
      vector<string> vecFiles;
      vector<string>::iterator  it_pos;
      //@todo 已下载文件过滤
      for (it_pos = vecFiles.begin(); it_pos != vecFiles.end(); ) {  
        string strTmp = *it_pos;
        if( objDownHis.checkHisList( strTmp.c_str() ) ){ //判断是否已下载过, 已下载则从列表删除
          g_Log << TIME << "file:[" << *it_pos << "] found "<< END; //
          it_pos = vecFiles.erase(it_pos);
        }else
          it_pos++;
      }

错误: code3
      vector<string> vecFiles;
      vector<string>::iterator  it_pos;
      //@todo 已下载文件过滤
      for (it_pos = vecFiles.begin(); it_pos != vecFiles.end(); it_pos++) {  
        string strTmp = *it_pos;
        if( objDownHis.checkHisList( strTmp.c_str() ) ){ //判断是否已下载过, 已下载则从列表删除
          g_Log << TIME << "file:[" << *it_pos << "] found "<< END; //
          vecFiles.erase(it_pos);
        }
      }


code3 错误的原因为, vecFiles.erase(it_pos); 当前的it_pos已经被删除了, 再下一次循环的时候 it_pos++, 访问非法内存..

然后回过头来看code1, vecFiles.erase(it_pos++); 在当前的it_pos已经被删除的时候, it_pos已经指向下一个位置了. 虽然这里逻辑上是错误的. 但是利用c语法的特性产生了一个正确的结果, 算是一个技巧. 不算是一门技术.

code2, it_pos = vecFiles.erase(it_pos); erase删除的时候, 也返回了下一个指针的位置,我们将这个位置保留了, 所以这种做法也是正确的.


另外一个移植性比较好的做法是remove_if 和一个仿函数.

仿函数可以是:
struct check {
    check( Object * objDownHis ) : m_obj( objDownHis ) {}
    check( const check & c ) : m_obj( c.m_obj ) {}

    bool operator()(const string & s) const {
       if ( m_obj->checkHisList( s.c_str() ) {
            g_Log .........
            return true;
       }
       return false;
    }
    Object * m_obj;
};

vecFiles.erase( std::remove_if( vecFile.begin(), vecFile.end(), check( &objDownHis ) );


鸣谢p大, lancey, jackz 排名不分先后.. 全按交流时间顺序...

转载于:https://www.cnblogs.com/yang3wei/archive/2012/05/22/2739744.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STL vectorC++标准模板库(STL)中的容器之一,用于存储和管理动态大小的元素序列。它提供了一些便利的操作和功能,比如自动调整大小、快速随机访问、插入和删除元素等。 你可以使用vector来存储任何类型的元素,包括基本数据类型和自定义对象。vector使用连续的内存来存储元素,并支持在常量时间内访问任意位置的元素。 下面是一些常用的vector操作: 1. 创建vector: 可以使用默认构造函数或将现有的序列作为参数传递给构造函数来创建vector对象。 ```cpp #include <vector> std::vector<int> numbers; // 声明一个空的vector std::vector<int> numbers = {1, 2, 3, 4}; // 使用初始值列表创建vector ``` 2. 访问元素: 可以使用下标运算符([])来访问vector中的元素。 ```cpp std::vector<int> numbers = {1, 2, 3, 4}; int firstElement = numbers[0]; // 访问第一个元素 int lastElement = numbers[numbers.size() - 1]; // 访问最后一个元素 ``` 3. 添加和删除元素: 可以使用push_back()函数将元素添加到vector的末尾,并使用pop_back()函数删除末尾的元素。 ```cpp std::vector<int> numbers; numbers.push_back(1); // 在末尾添加元素 numbers.pop_back(); // 删除末尾的元素 ``` 4. 大小操作: 可以使用size()函数获取vector中元素的数量,并使用empty()函数检查vector是否为空。 ```cpp std::vector<int> numbers = {1, 2, 3, 4}; int size = numbers.size(); // 获取元素数量 bool isEmpty = numbers.empty(); // 检查是否为空 ``` 5. 迭代器: 可以使用迭代器遍历vector中的元素。 ```cpp std::vector<int> numbers = {1, 2, 3, 4}; for (auto it = numbers.begin(); it != numbers.end(); ++it) { std::cout << *it << " "; // 输出每个元素 } ``` 这些只是vector的一些基本操作,STL vector还提供了许多其他功能和算法,可以根据需求进行使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值