Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

Iterator Invalidation ใน C++

ใน C++ มี container หลายอย่าง vector, list, set, map ใช้ iterator วนลูป ต้องระวังเพราะ iterator อาจ invalidated ได้ หากรูปทรงหรือขนาดเปลี่ยนแปลง ตัวอย่างต่อไปแสดงปัญหา invalidation

ตัวอย่างปัญหา

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> vec{11, 55, 110, 155, 220};
    for (auto it = vec.begin(); it != vec.end(); it++)
        if ((*it) == 110)
            vec.push_back(89); // แทรกค่าใหม่ขณะวนลูป
    for (auto it = vec.begin(); it != vec.end(); it++)
        cout << (*it) << " ";
}

ผลลัพธ์

11 55 110 155 220 89 89

ในโปรแกรมนี้ขนาด vector ไม่ได้กำหนดไว้ล่วงหน้า ขณะวนลูปเพิ่มค่า ถ้า vector ไม่มีพื้นที่ จะจองบล็อกหน่วยความจำใหม่และคัดลอกทุกสมาชิก แต่ iterator ยังชี้ที่เก่า อาจเกิด invalidation

กฎสำหรับ iterator invalidation:

InsertionErasureResizing
VectorIterator ชี้ก่อนจุดแทรกไม่ได้รับผลกระทบ แต่ตัวอื่น invalid ถ้าขนาดเพิ่ม ทุก iterator invalidIterator และ reference หลังจุดลบ invalid ทั้งหมดเหมือน insert/erase
Dequeทุก iterator และ reference invalid ถ้าแทรกไม่ใช่ท้ายลบจากตำแหน่งไหนก็ตามนอกจากท้าย ทุก iterator invalidเหมือน insert/erase
Listทุก iterator และ reference ไม่ได้รับผลเฉพาะ iterator/reference ที่ชี้โหนดที่จะลบ ถูกกระทบเหมือน insert/erase
Set, map, multiset, multimapทุก iterator และ reference ไม่ได้รับผลเฉพาะ iterator/reference ที่ชี้โหนดที่จะลบ ถูกกระทบ---