美文网首页
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