大家知道vector容器与数组的不同之处在于,vector可以自动扩容它的容量,是一个动态的数组,而我们的普通数组的容量时固定死的。当vector内元素的数量等于vector容量的时候,再向vector中插入数据,vector会自动申请一块儿更大的内存空间,并将原来的数据拷贝过去,并存将新的元素插入。而原来的内存空间将被释放。
下面是在VS2017上的例子的运行结果:
可见插入数据后,vector的首元素地址发生了改变,也就是说该vector的位置发生了改变。
看上图,可知原vector的容量为0,插入一个数据以后,容量扩大到了1,而迭代器 it的地址是未插入元素之前的地址,插入元素后,vector由于新开辟空间导致vector的地址发生了变化,原内存空间被释放,导致用迭代器访问vector的元素时,出现了内存错误。这也就是所谓的迭代器失效。
不止是插入,删除也会导致迭代器失效。
如上图,用一个迭代器指向一个vector,在删除一个数据之后,使用该迭代器访问vector中的元素时,发生了错误。
那么问题来了,我们知道图中it 迭代器,指向的是该vector的地址,也就是第一个元素的地址,而我们删除的是最后一个元素,第一个元素并没有被删除,为什么还会出现访问出错。
原因是:比如一个vector中按顺序插入了1 2 3 三个元素,删除一个元素只是将size–,而第三个元素所对应的位置存储的依然是3,当以用下标访问该vector时,是以size作为访问终止条件时,因此3不会被访问到,也就与3被删除了是相同的道理。但是用迭代器访问时就不同了,它是以地址访问与下标无关。难免就会访问到3,就会出现访问越界,这是一个很难发现的问题,因此为了避免这个问题,当我们删除一个元素之后,再使用迭代器访问该vector时就会报错,帮我们解决了这个问题。
当然并非是对vector而言,对其他的容器来说,只要使用了删除或者插入接口时,迭代器都会失效。
这是我对迭代器失效的理解,有解释不到位的地方,还希望大佬们提出来。