zoukankan      html  css  js  c++  java
  • C++中erase函数的使用,可以用来删除内存擦除

    erase函数的原型如下:
    (1)string& erase ( size_t pos = 0, size_t n = npos );
    (2)iterator erase ( iterator position );
    (3)iterator erase ( iterator first, iterator last );
    也就是说有三种用法:
    (1)erase(pos,n); 删除从pos开始的n个字符,比如erase(0,1)就是删除第一个字符
    (2)erase(position);删除position处的一个字符(position是个string类型的迭代器)
    (3)erase(first,last);删除从first到last之间的字符(first和last都是迭代器)
    下面给你一个例子:
    复制代码
    #include <iostream>
    #include <string>
    using namespace std;

    int main ()
    {
      string str ("This is an example phrase.");
      string::iterator it;

      // 第(1)种用法
      str.erase (10,8);
      cout << str << endl;        // "This is an phrase."

      // 第(2)种用法
      it=str.begin()+9;
      str.erase (it);
      cout << str << endl;        // "This is a phrase."

      // 第(3)种用法
      str.erase (str.begin()+5, str.end()-7);
      cout << str << endl;        // "This phrase."
      return 0;
    }
     
     

    erase()函数的功能是用来删除容器中的元素
    删除某个容器里的某个元素:c.erase(T);
    看似一个简单的动作,然而对不同类型的容器,内部却做了截然不同的事情,后面介绍。
    假设有这样一个题目,将某个容器中所有满足条件N == X的元素删除,按照常规的思路应该有类似这样的代码:

    // 假设Container和container分别表示一种容器和对应的一个对象
    Container<T>::iterator it;
    for (it = container.begin(); it != container.end(); ++it) {
      if (N == X)
        container.erase(it);
    }

    然而这样的代码对于任一种容器都是错误的STL中erase()小心使用

    容器按内存分配方式可以分为链表容器和数组容器。

    所谓的链 表容器指的是一种表现方式,包括list、slist等这样基于节点的容器(动态分配内存块)和set、map、multiset、multimap等关 联容器(平衡树实现),而数组容器指的是在一块连续的内存上保存元素的连续内存容器,比如vector、deque、string等。

    链表容器 以list为例,当执行container.erase(it)时,确实第一个满足条件的元素删除了,但这时it指针已经被删除了,它也不指向任何元素 了,所以也只能到此为止了,也就是说上面的代码对于链表容器来说只能正确删除第一个满足条件的元素,针对这个问题我们首先想到的就是在删除指针之前,给其 做个备份。

    将这个临时变量直接建立在erase实现里,这样做更简洁,也显得专业些。

    list<int>::iterator it; 
      for (it = lt.begin(); it != lt.end(); ) {
        if (*it % 2 == 0)
          lt.erase(it++); //这里是关键
        else
          ++it;
      }

     

    链表容器使用erase删除节点还有一个特点,就是会将下一个元素的地址返回,所以也可以这样实现:

    list<int>::iterator it; 
      for (it = lt.begin(); it != lt.end(); ) {
        if (*it % 2 == 0)
          it = lt.erase(it);//自动返回下一个元素的地址,不用再主动前移指针
        else
          ++it;
      }

     

    vector<int>::iterator it = v.begin();
      for (it = v.begin(); it != v.end(); ) { 
        if (*it % 2 == 0)
          v.erase(it);//删除元素后,后面元素自动往前移,不用挪动指                  
        else
          ++it;
      }
     网上有说在VS2005里面上面的v.erase(it)写法是行的  VS2008及2010却运行会出现错误 会出现
    vector erase iterator outside range  最保险的做法是将v.erase(it)改成 it=v.erase(it)

  • 相关阅读:
    spark 源码分析之五--Spark RPC剖析之创建NettyRpcEnv
    spark 源码分析之四 -- TaskScheduler的创建和启动过程
    spark 源码分析之三 -- LiveListenerBus介绍
    spark 源码分析之二 -- SparkContext 的初始化过程
    scala class中孤立代码块揭秘
    spark 源码分析之一 -- RDD的四种依赖关系
    spark streaming 接收kafka消息之五 -- spark streaming 和 kafka 的对接总结
    spark streaming 接收kafka消息之四 -- 运行在 worker 上的 receiver
    spark streaming 接收kafka消息之三 -- kafka broker 如何处理 fetch 请求
    spark streaming 接收kafka消息之二 -- 运行在driver端的receiver
  • 原文地址:https://www.cnblogs.com/loda333/p/5229980.html
Copyright © 2011-2022 走看看