คำอธิบาย
Iterator Invalidation** เกิดขึ้นเมื่อ iterator ชี้ไปที่ตำแหน่งที่ไม่ถูกต้องอีกต่อไป เนื่องจาก container เปลี่ยนแปลงขนาดหรือจัดสรรหน่วยความจำใหม่
กรณีที่พบบ่อย
- vector: push_back/insert/erase อาจทำให้ reallocate → iterator ทั้งหมด invalid
- list/deque: insert/erase invalidates เฉพาะ iterator ที่ถูกลบ
- map/set: insert/erase invalidates เฉพาะ iterator ที่ถูกลบ
ตัวอย่างปัญหา
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int> v = {1, 5, 10, 15, 20};
// ผิด: modify vector ขณะ iterate
for(auto it = v.begin(); it != v.end(); it++) {
if(*it == 5) {
v.push_back(-1); // อาจ reallocate → it invalid!
}
}
// ถูกต้อง: ใช้ index หรือเก็บค่าก่อน
for(size_t i = 0; i < v.size(); i++) {
if(v[i] == 5) v.push_back(-1); // ปลอดภัยกว่า (แต่ size เปลี่ยน)
}
// หรือใช้ erase-remove idiom
// v.erase(remove(v.begin(), v.end(), 5), v.end());
for(int x : v) cout << x << " ";
return 0;
}
แนวทางป้องกัน
- หลีกเลี่ยงการ modify container ขณะ iterate (ยกเว้น erase ที่คืน iterator ใหม่)
- ใช้ index-based loop แทน iterator
- เก็บค่าที่ต้องการลบ/แก้ไขไว้ แล้วทำในภายหลัง
- ใช้
eraseที่คืน iterator ถัดไป (C++11+)