问题
最近碰到了一个比较低级的错误,首先大家可以先先思考一下下面的代码可能会发生什么问题
std::vector<int> array = { 1, 2, 3 };
for (const auto& e : array) {
array.push_back(e + 3);
}
即在遍历一个vector的时候同时往这个vector中插入新的元素,当然这是一种不推荐的,甚至是错误的写法。
在以上代码中,如果是插入元素,则可能不会影响已存在的元素的迭代器,因为push_back或者emplace_back的做法是将终止迭代器指向新插入的元素,但是这样思考并没有考虑vector的容量。若vector的容量不够的话,则会为vector开辟一个原来容量两倍的新的内存,并把数据迁移到新的内存地址,这样一来就会导致原有迭代器失效,便会发生未定义的行为。
拓展
除了vector,stl中还存在其他的很多容器,以比较常用的几个容器为例:
map或set: 在遍历的过程中删除元素可能会导致迭代器失效,若在遍历的过程中添加元素,则可能会打乱原有顺序,导致迭代器位置失效。
list: 在遍历的过程中增删元素安全,删除或者插元素不会使迭代器失效,并且增删元素实时有效。
queue, stack等没有迭代器的容器不需要考虑迭代器的安全问题。