昨天面試的時(shí)候,面試官突然問到這個(gè)問題,一面懵逼,感覺一樣,回來試了一下,還真是不一樣,做個(gè)小計(jì)。
STL中,關(guān)于vector rease的源碼如下(其中以清除某個(gè)位置元素函數(shù)為例):
iterator rease(iterator position)
{
if (position + 1 != end())
copy(position + 1, finish, position);
--finish;
destroy(finish);
return position;
}
可以看到源碼中返回的是一個(gè)迭代器類型,現(xiàn)在做一個(gè)測(cè)試,分別在windows和Linux下。
Windows下的vector erase
vector<int> ve = { 1, 2, 3, 4, 5 };
for (auto iter = ve.begin(); iter != ve.end(); ++iter)
{
cout << *iter << endl;
if (*iter == 3)
{
ve.erase(iter); //編譯OK,運(yùn)行會(huì)出現(xiàn)問題,迭代器失效
}
}
因?yàn)檫\(yùn)行時(shí),發(fā)現(xiàn)3這個(gè)元素并刪除,此時(shí)迭代器失效變成野指針,如果要是在遍歷過程中繼續(xù)處理后面元素可以這樣寫。
vector<int> ve = { 1, 2, 3, 4, 5 };
for (auto iter = ve.begin(); iter != ve.end(); ++iter)
{
cout << *iter << endl;
if (*iter == 3)
{
ve.erase(iter); //出現(xiàn)野指針
//方法1:返回刪除元素的下一個(gè)位置,指向4,但是for中又有一個(gè)++,沒有驗(yàn)證第四個(gè)元素
//iter = ve.erase(iter);//返回刪除元素的下一個(gè)位置
//方法2:從頭開始遍歷
//iter = ve.begin();
}
}
如果想不跳過,也不從頭開始,可以不在for中寫++iter,而是在for大括號(hào)中寫++iter,防止跳過刪除元素后面的那個(gè)元素。
在Linux下的vector erase
同樣的代碼,發(fā)現(xiàn)有些不同,在windows下的野指針居然能通過,郁悶
std::vector<int> ve = {1, 2, 3, 4, 5};
for(auto iter = ve.begin(); iter != ve.end(); ++iter)
{
if(*iter == 3)
{
auto i = ve.erase(iter); //居然可以成功
std::cout << "*i: " << *i << std::endl; //*i: 4
}
}