【问题标题】:Programmatically determine if std::string uses Copy-On-Write (COW) mechanism以编程方式确定 std::string 是否使用 Copy-On-Write (COW) 机制
【发布时间】:2011-05-28 14:59:33
【问题描述】:

跟进question 的讨论,我想知道使用本机 C++ 的人如何以编程方式确定他们使用的 std::string 实现是否使用 Copy-On-Write (牛)

我有以下功能:

#include <iostream>
#include <string>

bool stdstring_supports_cow()
{
   //make sure the string is longer than the size of potential
   //implementation of small-string.
   std::string s1 = "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789";
   std::string s2 = s1;
   std::string s3 = s2;

   bool result1 = (&s1[0]) == (&s2[0]);
   bool result2 = (&s1[0]) == (&s3[0]);

   s2[0] = 'X';

   bool result3 = (&s1[0]) != (&s2[0]);
   bool result4 = (&s1[0]) == (&s3[0]);

   s3[0] = 'X';

   bool result5 = (&s1[0]) != (&s3[0]);

   return result1 && result2 &&
          result3 && result4 &&
          result5;
}

int main()
{
  if (stdstring_supports_cow())
      std::cout << "std::string is COW." << std::endl;
   else
      std::cout << "std::string is NOT COW." << std::endl;
   return 0;
}

问题是我似乎找不到返回 true 的 C++ 工具链。我对如何为 std::string 实现 COW 的假设是否存在缺陷?

更新:基于 kotlinski cmets,我已经更改了函数中对 data() 的可写引用的使用,现在对于某些实现,它似乎返回“true”。

bool stdstring_supports_cow()
{
   //make sure the string is longer than the size of potential
   //implementation of small-string.
   std::string s1 = "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789"
                    "012345678901234567890123456789";
   std::string s2 = s1;
   std::string s3 = s2;

   bool result1 = s1.data() == s2.data();
   bool result2 = s1.data() == s3.data();

   s2[0] = 'X';

   bool result3 = s1.data() != s2.data();
   bool result4 = s1.data() == s3.data();

   s3[0] = 'X';

   bool result5 = s1.data() != s3.data();

   return result1 && result2 &&
          result3 && result4 &&
          result5;
}

注意:根据N2668: "Concurrency Modifications to Basic String",在即将发布的 C++0x 标准中,COW 选项将从 basic_string 中删除。感谢 James 和 Beldaz 提出这个问题。

【问题讨论】:

标签: c++ algorithm string copy-on-write


【解决方案1】:

使用&amp;s1[0] 获取地址不是你想要的,[0] 返回一个可写引用并会创建一个副本。

改用 data(),它返回一个 const char*,你的测试可能会通过。

【讨论】:

  • +1 我按照您的建议进行了更改,目前看起来不错:codepad.org/zDJNcqUx
  • 建议你使用 data(),而不是 c_str()。 c_str() 必须返回一个以 null 结尾的字符串。所以也许 std::string 需要为那个调用创建一个新的缓冲区。 (不太可能,但允许)
【解决方案2】:

写时复制范式依赖于知道何时进行写操作。只要对象返回可写引用,就会发生这种情况。

如果您使用对字符串的 const 引用,如果该类专门用于在返回对数据的 const 引用时禁用复制,则您可以比较地址。

【讨论】:

  • @Zenikoder,也许当我建议对字符串使用 const 引用时我并不清楚?他们返回的任何内容都是不可写的,不应触发副本。
猜你喜欢
  • 1970-01-01
  • 2011-11-13
  • 2011-09-23
  • 2019-01-29
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多