2016-11-28 98 views
0

我在這裏尋找更深入的解釋,而不僅僅是如何獲得工作代碼。我知道如何編寫更短的代碼來擦除元素。我在這裏寫了這個測試代碼,以查明刪除後的失敗點。似乎不僅i迭代器變得無效,而且還有.end()迭代器......這很有趣。迭代器的有效性

這是什麼原因?

deque<shared_ptr<Vehicle>> data; 
    data.push_back(shared_ptr<Vehicle>(new Vehicle("porsche"))); 
    data.push_back(shared_ptr<Vehicle>(new Vehicle("fiat"))); 
    data.push_back(shared_ptr<Vehicle>(new Vehicle("fiat"))); 
    data.push_back(shared_ptr<Vehicle>(new Vehicle("bmw"))); 
    data.push_back(shared_ptr<Vehicle>(new Vehicle("fiat")));  

    auto end = data.end(); 
    for(auto i = data.begin(); i != end;) 
    { 

     if((*i)->getName() == "fiat") 
     { 
      auto ti = i; 
      ++ti; 
      end = data.end(); //above erase, works but not logical 
      data.erase(i); 
      i=ti; 
     } 
     else 
     { 
      ++i; 
      end = data.end(); 
     } 
    } 

但這不起作用?

deque<shared_ptr<Vehicle>> data; 
data.push_back(shared_ptr<Vehicle>(new Vehicle("porsche"))); 
data.push_back(shared_ptr<Vehicle>(new Vehicle("fiat"))); 
data.push_back(shared_ptr<Vehicle>(new Vehicle("fiat"))); 
data.push_back(shared_ptr<Vehicle>(new Vehicle("bmw"))); 
data.push_back(shared_ptr<Vehicle>(new Vehicle("fiat")));  

auto end = data.end(); 
for(auto i = data.begin(); i != end;) 
{ 

    if((*i)->getName() == "fiat") 
    { 
     auto ti = i; 
     ++ti; 
     data.erase(i); 
     end = data.end(); //Bellow erase...more logical but crashes 
     i=ti; 
    } 
    else 
    { 
     ++i; 
     end = data.end(); 
    } 
} 

我猜,有一些在這裏執行層面的問題。也許是編譯器錯誤。使用GCC 4.8.2。

+0

您可能在代碼中的其他地方存在導致未定義行爲的錯誤。您需要編輯您的問題並提供[mcve]。 –

+0

迭代器行爲因容器類型而異。 「數據」究竟是什麼? – 1201ProgramAlarm

+0

已添加代碼。保證沒有錯誤別的地方。即。班車正常實施等等。我不會發布它以保持代碼的專注和清潔。 – code

回答

0

您正在調用未定義的行爲。從語言規範,約deque::erase

是刪除一個雙端隊列的最後一個元素無效僅在過去的最末端 iterator和所有迭代器和引用擦除單元的擦除操作。擦除操作會擦除一個deque的第一個元素,但不會擦除最後一個元素,只會使迭代器和對擦除的元素的引用無效。既不擦除第一個元素也不擦除deque的最後一個元素的擦除操作會使過去末端迭代器和所有迭代器以及對deque所有元素的引用無效。

在你的情況,你的end迭代器總是越來越重挫,它只是運氣,它在所有工作。在第二種情況下的崩潰很可能是由於i的操作,而不是data.end的呼叫。