В C ++ STL есть то, что называется недействительностью указателя. Это означает, что когда вы получаете указатель на элемент в контейнере, а затем модифицируете контейнер, после модификации ваш указатель может перестать действовать.
Правило аннулирования указателя определяется стандартом и варьируется от контейнеров к контейнерам, операций к операциям.
В вашем случае у вас есть std::vector
. Ссылка / указатель / итератор на элемент вектора больше не действительны, если вы emplace_back
и вектор требует большей емкости для добавленного элемента. В этом случае вектор выделяет еще большее пространство в памяти и перемещает туда все свои элементы.
Но подождите!
Вы берете указатель data()
прямо из строки! Почему этот указатель также недействителен? Разве wstring
не должен быть легкой структурой, которая просто содержит указатель на некоторый буфер кучи?
Ну, это магия SSO (Small String Optimization). Если ваша строка достаточно мала, wstring
просто сохраняет свой буфер в самой структуре данных (а не хранит указатель на буфер). В этом случае, когда вы перемещаете его, конечно, указатель становится недействительным.
Ваша строка довольно мала (1 широкий символ), поэтому она удовлетворяет условию SSO. Если вы используете более длинные:
std::vector<std::wstring> vecWstr;
vecWstr.emplace_back(L"asdfghjkl");
wchar_t* data1 = vecWstr[0].data(); //<-This pointer needed for future use.
vecWstr.emplace_back(L"qwertyuiop");
wchar_t* data2 = vecWstr[0].data();
if (data1 != data2)
MessageBox(0, L"Error, not equal.", L"Compare", 0);
return 0;
Окно сообщения, вероятно, не появится.
Однако вы не можете контролировать длину строки времени выполнения, и вы не знаете, как ваш компилятор будет реализовывать SSO, поэтому не кодируйте этот путь!
Вместо этого вы можете использовать метод reserve
(как предложил songyuanyao) или использовать другие контейнеры, которые не делают недействительными указатели при добавлении элемента. Пожалуйста, обратитесь к std :: list и std :: deque . Прочитайте разделы об их недействительности указателя / ссылки / итератора.