關於vector的erase問題處理

來源:互聯網
上載者:User

Vector的erase成員函數有許多容易導致問題的情況.其中以迭代器失效問題最為常見.

關於迭代器的失效問題,以及erase如何刪除vector中指定值(可能不止一個),我曾今也對erase的使用方式和內容結合起來寫過一些字.

博文地址:http://blog.csdn.net/yuanweihuayan/article/details/6790516

似乎對於刪除的解析已經夠全面了.可是最近在項目裡面發現一個很奇怪的問題,跟蹤了很久都沒有發現是什麼問題導致的.

今天知道了問題的原因,但是為什麼會這樣,我還是不清楚.看來STL這塊還需加大力度學習它.

源碼如下:

struct Usr{string strUiD;string strSrnName;string strNickName; string strDesc; string strGender; string strIcon; string strVtitle; string strVType; Usr(){    strUiD = "";strSrnName = "";strNickName = "";strDesc = "";strGender = "";strIcon = "";strVtitle = "";strVType = "";}Usr( string strUid,string strSrnName,string strNickName ){SetData( strUid,strSrnName,strNickName );}void SetData( string strUid,string strSrnName,string strNickName ){this->strUiD = strUid;this->strSrnName = strSrnName;this->strNickName = strNickName;strDesc = "";strGender = "";strIcon = "";strVtitle = "";strVType = "";}void operator=( const Usr& usr ){if ( usr.strUiD == strUiD){return;}strSrnName = usr.strSrnName;strNickName = usr.strNickName;strDesc = usr.strDesc;strGender = usr.strGender;strIcon = usr.strIcon;strVtitle = usr.strVtitle;strVType = usr.strVType;}bool operator==( Usr& usr ){if ( usr.strUiD == strUiD ){return true;}return false;}bool isEqual( Usr usr ){if ( usr.strUiD == strUiD ){return true;}return false;}};vector<Usr> vecUsr;Usr usr( "10001","ysl","袁孫良" );vecUsr.push_back( usr );usr.SetData( "10002","zxy","張學友" );vecUsr.push_back( usr );usr.SetData( "10003","ldh","劉德華" );vecUsr.push_back( usr );for ( vector<Usr>::iterator iterUsr = vecUsr.begin();iterUsr != vecUsr.end();iterUsr ++ ){if ( iterUsr->strUiD == "10001" ){vector<Usr>::iterator iterEnd = vecUsr.erase( iterUsr );if ( iterEnd != vecUsr.end() ){TRACE("success");break;}}}TRACE( "\n***************************************************************\n" );for ( vector<Usr>::iterator iterTemp= vecUsr.begin();iterTemp != vecUsr.end();iterTemp ++ ){CString strFormat;strFormat.Format( "編號:%s,  暱稱:%s\n",iterTemp->strUiD.c_str(),iterTemp->strNickName.c_str() );TRACE( strFormat.GetBuffer() );}

先看輸出結果:

success

***************************************************************

編號:10001,  暱稱:張學友

編號:10002,  暱稱:劉德華

這個結果很令人費解.

strUiD好像整體往下"移動"一位

採用單步調試或者TRACE來檢查程式的資料情況,(這裡我採用TRACE,原因很簡單,單步調試對迭代器不起啥作用).

加入的調試資訊如下:

vector<Usr> vecUsr;Usr usr( "10001","ysl","袁孫良" );vecUsr.push_back( usr );usr.SetData( "10002","zxy","張學友" );vecUsr.push_back( usr );usr.SetData( "10003","ldh","劉德華" );vecUsr.push_back( usr );TRACE( "\n***************************************************************\n" );for ( vector<Usr>::iterator iterTemp= vecUsr.begin();iterTemp != vecUsr.end();iterTemp ++ ){CString strFormat;strFormat.Format( "編號:%s,  暱稱:%s\n",iterTemp->strUiD.c_str(),iterTemp->strNickName.c_str() );TRACE( strFormat.GetBuffer() );}TRACE( "\n***************************************************************\n" );for ( vector<Usr>::iterator iterUsr = vecUsr.begin();iterUsr != vecUsr.end();iterUsr ++ ){if ( iterUsr->strUiD == "10001" ){vector<Usr>::iterator iterEnd = vecUsr.erase( iterUsr );if ( iterEnd != vecUsr.end() ){CString strFormat;strFormat.Format( "編號:%s,  暱稱:%s\n",iterEnd->strUiD.c_str(),iterEnd->strNickName.c_str() );TRACE( strFormat.GetBuffer() );break;}}}TRACE( "\n***************************************************************\n" );for ( vector<Usr>::iterator iterTemp= vecUsr.begin();iterTemp != vecUsr.end();iterTemp ++ ){CString strFormat;strFormat.Format( "編號:%s,  暱稱:%s\n",iterTemp->strUiD.c_str(),iterTemp->strNickName.c_str() );TRACE( strFormat.GetBuffer() );}

程式的執行結果如下:

***************************************************************

編號:10001,  暱稱:袁孫良

編號:10002,  暱稱:張學友

編號:10003,  暱稱:劉德華

***************************************************************

編號:10001,  暱稱:張學友

***************************************************************

編號:10001,  暱稱:張學友

編號:10002,  暱稱:劉德華

結果令人詫異,iterEnd返回的本是10001後面的資料,(即編號:10002,  暱稱:張學友),結果返回id和暱稱對不上,更為甚者,ID居然是10001.

很多人看到這個程式很疑惑,為什麼代碼裡面會有這麼多的操作符的重載?

這個問題還要追溯到泛型演算法.泛型演算法很多操作都要重載比較操作符等一系列的操作符.如果我們的程式沒有這些操作符.程式無法編譯.

一般的C++教材裡面之所以不存在重載的問題,主要原因是他的類型一般是單一資料型別;如vector<int>,vector<string>等..

這些東西系統都內建了比較操作符.所以...

我們把賦值操作符去掉,發現整個程式正常運行.10001記錄

程式運行結果如下:

***************************************************************

編號:10001,  暱稱:袁孫良

編號:10002,  暱稱:張學友

編號:10003,  暱稱:劉德華

***************************************************************

編號:10002,  暱稱:張學友

***************************************************************

編號:10002,  暱稱:張學友

編號:10003,  暱稱:劉德華

看到erase函數裡面實際上調用了copy,而這個函數會和我們定義的賦值操作符有衝突.具體情況還不是很清楚.這個問題等我深入STL時在做結論.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.