美文网首页
Vector中使用erase函数的分析

Vector中使用erase函数的分析

作者: EVANMORE | 来源:发表于2018-02-26 21:49 被阅读42次

    参看如下这段代码,我们遍历一个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循环中当查找到元素2的时候,就把这个元素从vector中移除;然后第二个循环把删掉一个元素的vector打印出来;
    我们期望的打印结果应该是这样的

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

    然而,实际打印的时候,结果却是,

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

    最后一个元素没有打印出来,这是什么原因呢?
    这里我们尝试一下把所有的iterator的地址打印出来,0x30表示地址的后16bit

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

    找到2的时候,it指向地址0x34,调用erase删除这个节点后,内存中存放就变成了如下这个样子

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

    由于vector中存放的内容在地址上必须是连续的,所以实际上所有后面的元素都往前移了一个位置。
    而迭代器it这个时候还是指向原来的0x34的位置,所以下一次for循环it就会指向end了。
    所以在实际编码过程中要避免这种实现方式,因为如果找到你想删除的元素的时候it已经指向了最后元素了;删除了这个元素以后,it就会变成一个野指针,for循环会变成死循环。

    相关文章

      网友评论

          本文标题:Vector中使用erase函数的分析

          本文链接:https://www.haomeiwen.com/subject/cxsuxftx.html