今天看Scott Meyers大師的stl的用法,,看到了我前段時(shí)間犯的一個(gè)錯(cuò)誤,發(fā)現(xiàn)我寫(xiě)的代碼和他提到錯(cuò)誤代碼幾乎一模一樣,有關(guān)stl容器刪除元素的問(wèn)題,,錯(cuò)誤的代碼如下: std::vector<struct> mFriendList; ... std::vector<struct>::iterator iter = mFriendList.begin(); for ( ; iter != mFriendList.end(); ++iter) { if (...) mFriendList.erase(iter); } 記得當(dāng)時(shí)Once給我說(shuō)過(guò)這個(gè)問(wèn)題,還給我改過(guò)代碼,,我當(dāng)時(shí)不明白為什么,,只知道程序執(zhí)行的時(shí)候如果if為true那么程序就肯定會(huì)崩潰。 大師的說(shuō)法是:當(dāng)容易中的一個(gè)元素被刪除時(shí),,指向該元素的所有迭代器都變得無(wú)效,。上面的代碼中,只要執(zhí)行了erase(iter),那么iter就會(huì)變得無(wú)效,,那么執(zhí)行++iter就肯定會(huì)出錯(cuò),。 在網(wǎng)上看到有人總結(jié)如下兩條: 1. 對(duì)于節(jié)點(diǎn)式容器(map, list, set)元素的刪除,插入操作會(huì)導(dǎo)致指向該元素的迭代器失效,,其他元素迭代器不受影響 2. 對(duì)于順序式容器(vector,,string,deque)元素的刪除,、插入操作會(huì)導(dǎo)致指向該元素以及后面的元素的迭代器失效 總結(jié)了一下,,并回想Once當(dāng)時(shí)給我改的代碼,所以正確的寫(xiě)法應(yīng)該是這樣的: 1.對(duì)于節(jié)點(diǎn)式容器 std::list<struct> mList; ... std::list<struct>::iterator iter = mList.begin(); for ( ; iter != mList.end(); ) { if (...) { //因?yàn)楣?jié)點(diǎn)式只會(huì)導(dǎo)致當(dāng)前節(jié)點(diǎn)迭代器失效,,所以刪除節(jié)點(diǎn)的同時(shí)對(duì)迭代器進(jìn)行后移的操作,,因?yàn)槠渌夭粫?huì)失效 mList.erase(iter++); } else { ++iter; } } 2.對(duì)于順序式容器 std::vector<struct> mVector; ... std::vector<struct>::iterator iter = mVector.begin(); for ( ; iter != mVector.end(); ) { if (...) { //這里就比較有說(shuō)法了,因?yàn)轫樞蚴饺萜鲿?huì)使本身和后面的元素迭代器都失效,,所以不能簡(jiǎn)單的++操作 //這里順序式容器的erase()會(huì)返回緊隨被刪除元素的下一個(gè)元素的有效迭代器 //而節(jié)點(diǎn)式容器的erase()的返回值是void,,這點(diǎn)我感覺(jué)太神奇了,確實(shí)太神奇了?。,。?! iter = mVector.erase(iter); } else { ++iter; } } |
|