2014-07-23 43 views
0

我試圖理解爲什麼下面的代碼的行爲方式是這樣:爲什麼在調用erase和push_back之後,下面的元素出現在這個C++向量的頭部和尾部?

std::vector<int*> k; 
for (int i = 0; i < 5; ++i) k.push_back(new int(i)); 

for (int i = 0; i < k.size(); ++i) 
    std::cout << "k[" << i << "]: " << *k[i] << "@" << k[i] << ", "; 
std::cout << std::endl; 

for (int i = 0; i < k.size(); ++i) { 
    int* p = k[i]; 
    delete p; 
    if (i >= 2) { 
     k.erase(k.begin(), k.begin() + i); 
     k.push_back(new int(5)); 
     break; 
    } 
} 

for (int i = 0; i < k.size(); ++i) 
    std::cout << "k[" << i << "]: " << *k[i] << "@" << k[i] << ", "; 
std::cout << std::endl; 

當我運行此,我們第一次打印k內容我看到這一點:

[0]: [email protected], k[1] [email protected], k[2]: [email protected], k[3]: [email protected], k[4]: [email protected] 

這是我的預期。然後,在擦除和推動後,我預計前兩個元素將消失,最後三個元素將被移動,第五個元素將出現在最後。不過,我得到這個:

k[0]: [email protected], k[1]: [email protected], k[2]: [email protected], k[5]: [email protected], 

我確實看到k[5]出現在結束後,其餘元件位移,但我不理解爲什麼它也出現爲第一要素了。

回答

1

vector::erase的第二個參數是迭代器的末尾。這是標準C++庫中迭代器範圍的典型形式。

因此,當i == 2語句k.erase(k.begin(), k.begin() + i)只刪除前兩個元素,留下剛剛刪除的元素仍然在向量中。當您嘗試使用刪除的指針時,這繼續導致虛假結果。

(從技術角度來看,erase也是未定義的行爲,因爲它涉及讀取已刪除的指針)。

也許,你看到k[0]: [email protected]而不是隨機垃圾的原因是你的new int重新分配到相同的空間,你只需delete;並且我猜k[5]:就是該行的錯字k[3]:

+0

完全正確!謝謝,我盯着這個很長一段時間,它一直在躲避我...... –

相關問題