Vector中使用erase函數(shù)的分析

參看如下這段代碼,我們遍歷一個vector,使用erase刪除其中的一個元素

    int a[3]={1,2, 3}; 
    std::vector<int> a_vec(a, a+3);
    std::vector<int>::iterator it;
    printf("member before erase: ");
    for(it = a_vec.begin(); it != a_vec.end(); it++)
    {
        printf("%d\t", *it);
        if(*it == 2)
        {
            a_vec.erase(it);
        }
    }
    printf("\n member after erase: ");
    for(it = a_vec.begin(); it != a_vec.end(); it++)
    {
        printf("%d\t", *it);
    }
    printf("\n");

第一個for循環(huán)中當(dāng)查找到元素2的時候,就把這個元素從vector中移除;然后第二個循環(huán)把刪掉一個元素的vector打印出來;
我們期望的打印結(jié)果應(yīng)該是這樣的

member before erase: 1  2 3
 member after erase: 1  3

然而,實(shí)際打印的時候,結(jié)果卻是,

member before erase: 1  2    
 member after erase: 1  3

最后一個元素沒有打印出來,這是什么原因呢?
這里我們嘗試一下把所有的iterator的地址打印出來,0x30表示地址的后16bit

0x30(1) == 0x34(2) == 0x38(3) == 0x3C(end)

找到2的時候,it指向地址0x34,調(diào)用erase刪除這個節(jié)點(diǎn)后,內(nèi)存中存放就變成了如下這個樣子

0x30(1) == 0x34(3) <- it == 0x38(end) ====

由于vector中存放的內(nèi)容在地址上必須是連續(xù)的,所以實(shí)際上所有后面的元素都往前移了一個位置。
而迭代器it這個時候還是指向原來的0x34的位置,所以下一次for循環(huán)it就會指向end了。
所以在實(shí)際編碼過程中要避免這種實(shí)現(xiàn)方式,因?yàn)槿绻业侥阆雱h除的元素的時候it已經(jīng)指向了最后元素了;刪除了這個元素以后,it就會變成一個野指針,for循環(huán)會變成死循環(huán)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容