Вставка в вектор во время итерации - плохая идея. Вставка данных может привести к перераспределению памяти, что делает недействительными итераторы. В этом случае емкости было недостаточно для вставки дополнительных элементов, что вызвало выделение памяти с другим адресом. Вы можете проверить это сами:
void test()
{
bool allValid = true;
int k = 0;
vector<int> v2(5, MAGIC);
k = 0;
for (vector<int>::iterator p = v2.begin(); p != v2.end(); p++, k++)
{
cout << v2.capacity() << endl; // Print the vector capacity
if (k >= 20) // prevent infinite loop
break;
if (*p != MAGIC) {
//cout << "Item# " << k << " is " << *p << ", not " << MAGIC <<"!" << endl;
allValid = false;
}
if (k == 2) {
for (int i = 0; i < 5; i++)
v2.push_back(MAGIC);
}
}
if (allValid && k == 10)
cout << "Passed test 3" << endl;
else
cout << "Failed test 3" << "\n" << k << endl;
}
Этот код выведет что-то вроде следующего:
5
5
5
10 <-- the capacity has changed
10
... skipped ...
10
10
Failed test 3
20
Мы можем видеть, что где k равно 2 (третья строка), емкость вектора удвоилось (четвертая строка), потому что мы добавляем новые элементы. Память перераспределяется, и векторные элементы, скорее всего, теперь находятся в другом месте. Вы также можете проверить это, напечатав векторный базовый адрес с помощью data
функции-члена вместо capacity
:
Address: 0x136dc20 k: 0
Address: 0x136dc20 k: 1
Address: 0x136dc20 k: 2
Address: 0x136e050 k: 3 <-- the address has changed
Address: 0x136e050 k: 4
... skipped ...
Address: 0x136e050 k: 19
Address: 0x136e050 k: 20
Failed test 3
20
Код написан плохо, вы можете сделать его более устойчивым, используя индексы вместо итераторов.