參看如下這段代碼,我們遍歷一個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)。