在C++ STL中,有一种叫做指针失效的东西。这意味着,当您获取容器中元素的指针,并且稍后修改容器时,修改后您的指针可能不再有效。
指针失效的规则是由标准定义的,并且在容器之间、操作之间有所不同。
就你而言,你有一个std::vector
。向量元素的引用/指针/迭代器不再有效,如果emplace_back
并且向量需要更大的容量来容纳添加的元素。在这种情况下,向量会在内存中分配另一个更大的空间,并将其所有元素移动到那里。
可是等等!
你正在服用data()
直接从字符串中获取指针!为什么这个指针也失效了呢?不应该wstring
是一个仅包含指向某个堆缓冲区的指针的轻量级结构吗?
嗯,这就是SSO(小字符串优化)的魔力。如果你的绳子足够小,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 建议的那样),或使用其他在添加元素时不会使指针无效的容器。请参阅标准::列表 https://en.cppreference.com/w/cpp/container/list and std::双端队列 https://en.cppreference.com/w/cpp/container/deque。阅读有关指针/引用/迭代器失效的部分。