196просмотров
3 сентября 2022 г.
provocationScore: 216
Еще одна проблема с переходом на низкоуровневые языки — операции с указателями (pointer). Про это знают, наверно, все программисты, но иногда случаются ситуации, в которых с первого раза и не предположить подводных камней. Рассмотрим следующий код:
vector<int> v;
v.push_back(1);
cout << v[0] << " ";
int p = &(--v.end()); (p) = 2;
cout << v[0] << " ";
(p) = 3;
cout << v[0] << " "; Данный код выведет на экран значения:
1 2 3 Казалось бы все как мы и предполагали.
Проблема данного кода в том, что вектор совершенно не гарантирует что данные будут все время лежать в одной и той же области памяти. В случае изменения размера — стандартная библиотека может переложить элементы в новую область памяти. Давайте немного поменяем исходный код:
vector<int> v; v.reserve(1); v.push_back(1);
cout << v[0] << " ";
int p = &(--v.end()); (p) = 2;
cout << v[0] << " "; v.reserve(3); (p) = 3;
cout << v[0] << " "; В лучшем случае эта вариация выведет на экран: 1 2 2, так как мы запишем последнее изменение в область памяти уже не имеющей отношения к вектору. В худшем же случае данный код просто упадет в попытке произвести запись в ненадлежащий сегмент.