在Xcode中运行以下C ++代码时:
std::wstring str1 = L"1111";
std::wstring str2 = str1;
void* ptr1 = (void*)str1.c_str();
void* ptr2 = (void*)str2.c_str();
结果是两个指针都相等。这是标准的吗? 在Visual Studio中情况并非如此。
答案 0 :(得分:2)
看起来该实现正在使用 copy-on-write (COW)优化,其中只有在执行写操作时才真正设置字符串内部状态 * 。这在C ++ 11之前的实现中是允许的,但我不认为这是C ++ 11以来的标准。
请注意,当您以非const方式访问字符串时,可以检查基础指针的地址是否发生更改,即使没有写入它也是如此:
str2[0];
对该表达式的求值应触发写操作,该操作将改变指针的地址。这是一个有效的例子:
#include <string>
#include <iostream>
int main()
{
std::wstring str1 = L"1111";
std::wstring str2 = str1;
std::cout << (void*)str1.c_str() << " " << (void*)str2.c_str() << std::endl;
str2[0]; // forces a write operation. c_str() changes.
std::cout << (void*)str1.c_str() << " " << (void*)str2.c_str() << std::endl;
}
在最近的gcc上,这会产生
0x8a8e014 0x8a8e014
0x8a8e014 0x8a8e03c
*有些非const访问可以触发写操作,即使它们没有语义上改变字符串,如上例所示。