Xcode - STL字符串赋值中的浅拷贝

时间:2015-05-20 08:12:47

标签: c++ xcode string c++11 stl

在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中情况并非如此。

1 个答案:

答案 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访问可以触发写操作,即使它们没有语义上改变字符串,如上例所示。