我有两个关于迭代器的问题。
I thought the once you define an iterator to an STL container such as a vector or a list, if you add elements to the containers then these iterators won't be able to access them. But the following code defines a list of five elements and then adds another element in each loop iteration and results in an infinite loop:
#include <iostream> #include <list> using namespace std; int main() { list<int> ls; for(int i = 0; i < 5; i++) { ls.push_back(i); } int idx = 0; for(list<int>::iterator iter = ls.begin(); iter != ls.end(); iter++) { cout << "idx: " << idx << ", *iter: " << *iter << endl; ls.push_back(7); idx++; } }
However, doing the same for a vector results in an error:
#include <iostream> #include <vector> using namespace std; int main() { vector<int> vec; for(int i = 0; i < 5; i++) { vec.push_back(i); } int idx = 0; for(vector<int>::iterator iter = vec.begin(); iter != vec.end(); iter++) { cout << "idx: " << idx << ", *iter: " << *iter << endl; vec.push_back(7); idx++; } }
I thought that when the vector container must be resized, it does so at powers of 2 and is located to a new area of memory, which is why you shouldn't define an iterator to a vector if you adding elements to it (since the iterators don't get passed to the new memory location). For example, I thought a vector containing 16 elements, after calling the push_back function, will be allocated space for 32 elements and the entire vector will be relocated. However, the this didn't happen for the following code. Was I just mistaken?
#include <iostream> #include <vector> using namespace std; int main() { vector<int> vec; for(int i = 0; i < 4; i++) { vec.push_back(i); cout << "address of vec: " << &vec << ", capacity: " << vec.capacity() << endl; } for(int i = 0; i < 20; i++) { vec.push_back(i); cout << "address of vec: " << &vec << ", capacity: " << vec.capacity() << endl; } }
vector
重新调整大小时,它的新存储可能从与旧存储相同的地址开始。即使你可以确保vector
增加了其capacity()
,也不能保证它位于不同的地址上。只有vector
的规则告诉你何时迭代器被认为是有效或无效的。 - Joe Zvector
的容量增加速率并没有被标准规定。只要保持push_back()
的摊销复杂度为 O(1)(并且保持其他方法的复杂度要求),实现可以以 1.5x、2x、3x 或任何它想要的速率进行。 - Cornstalks