【问题标题】:std::string copy constructor NOT deep in GCC 4.1.2?std::string 复制构造函数在 GCC 4.1.2 中不是很深?
【发布时间】:2013-05-17 08:43:59
【问题描述】:

我想知道我是否误解了什么:来自std::string 的复制构造函数复制其内容吗?

string str1 = "Hello World";
string str2(str1);

if(str1.c_str() == str2.c_str()) // Same pointers!
  printf ("You will get into the IPC hell very soon!!");

这将打印“你很快就会进入 IPC 地狱!!”这让我很烦。

这是std::string 的正常行为吗?我在某处读到它通常会进行深层复制。

但是,这按预期工作:

string str3(str1.c_str());

if(str1.c_str() == str3.c_str()) // Different pointers!
  printf ("You will get into the IPC hell very soon!!");
else
  printf ("You are safe! This time!");

它将内容复制到新字符串中。

【问题讨论】:

  • 尝试在您的第一个示例中修改str2(例如str2[0] = 'B';)并然后比较c_str()的值。
  • 不管怎样,GCC 4.7 在 C++03 和 C++11 模式下具有相同的行为(@Angew 的建议确实产生了不同的c_str() 值)。
  • 显然它会在您建议 @Angew 进行编辑后分配一个新的缓冲区。所以这似乎是某种“优化”……我们花了好几个小时才找到这个问题。*叹气*

标签: c++ gcc copy-constructor deep-copy stdstring


【解决方案1】:

您的string 实现完全有可能使用写时复制来解释该行为。尽管对于较新的实现(并且不符合 C++11 实现),这种情况不太可能发生。

标准对c_str 返回的指针的值没有任何限制(除了它指向一个以null 结尾的c 字符串),因此您的代码本质上是不可移植的。

【讨论】:

  • 为什么较新的实现不太可能使用 COW。
  • @user93353 如果您想符合 C++11,则无法实现 COW:stackoverflow.com/questions/12199710/…
  • @user93353:COW 会严重降低多线程环境中的性能。由于这个原因,它失去了很多人气(并在 C++11 中被禁止)。
  • @user93353 很多人不同意多线程。还有移动语义,它处理了很多 COW 曾经有用的经典案例。
  • @syam 这被认为是一个缺陷,可能会改变:stackoverflow.com/questions/12520192/… 和链接的线程。
【解决方案2】:

您的编译器中的std::string 实现必须进行引用计数。更改其中一个字符串,然后再次检查指针 - 它们会有所不同。

string str1 = "Hello World";
string str2(str1);

if(str1.c_str() == str2.c_str()) // Same pointers!
  printf ("You will get into the IPC hell very soon!!");

str2.replace(' ',',');

// Check again here.

这是 3 篇关于引用计数字符串的优秀文章。

http://www.gotw.ca/gotw/043.htm

http://www.gotw.ca/gotw/044.htm

http://www.gotw.ca/gotw/045.htm

【讨论】:

  • 我做到了,正如我在对问题本身的评论中指出的那样,就像上面所说的那样:它会在写入时复制!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多