vector中erase用法注意事項


以前就發現了vector中的erase方法有些詭異(^_^),稍不注意,就會出錯。今天又一次遇到了,就索性總結一下,尤其是在循環體中用erase時,由於vector.begin() 和vector.end()是變化的,因此就引入了錯誤的可能性。

erase的函數原型有兩種形式:

iterator erase(iterator position);

iterator erase(iterator first, iterator last);

 

vector<int> veci;
veci.push_back(1);
veci.push_back(2);
veci.push_back(3);
veci.push_back(4);
veci.push_back(5);
veci.push_back(3);
veci.push_back(2);
veci.push_back(3);

for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
{
      if( *iter == 3)
             veci.erase(iter);
}

乍一看這段代碼,很正常。其實這里面隱藏着一個很嚴重的錯誤:當veci.erase(iter)之后,iter就變成了一個野指針,對一個野指針進行 iter++ 是肯定會出錯的

查看MSDN,對於erase的返回值是這樣描述的:An iterator that designates the first element remaining beyond any elements removed, or a pointer to the end of the vector if no such element exists,於是改代碼:

for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
{
      if( *iter == 3)
             iter = veci.erase(iter);
}

這段代碼也是錯誤的:1)無法刪除兩個連續的"3"; 2)當3位於vector最后位置的時候,也會出錯(在veci.end()上執行 ++ 操作)

正確的代碼應該為:

for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); )
{
     if( *iter == 3)
          iter = veci.erase(iter);
      else
            iter ++ ;
}

 

為了避免對野指針進行操作,另一種解決方法如下:

vector<int>::iterator itor2;

for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); )
{
     if( *iter == 3)

     {   

           itor2=iter;
          veci.erase(itor2);
     }

      else
            iter ++ ;
}

 

要解決無法刪除兩個連續的3的另一種方法如下:

vector<int>  veci;

veci.erase(remove(veci.begin(),veci.end(),6),veci.end());

這里用到了remove()函數,

注:remove是個stl的通用算法std::remove(first,last,val)移除[first, last)范圍內等於val的元素在vector里面用就類似於iter = std::remove(vec.begin(), vec.end(), val)但這個函數只是把val移到vec的末尾,並不真正刪除真正刪除還是要調用一次erase函數


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM