C++ std::string构造函数

3

对此有何想法将不胜感激:

std::string s1 = "hello";
std::string s2 = std::string(s1);

我现在期望这两个字符串是独立的,也就是说,我可以将", world"添加到s2中,而s1仍然保持为"hello"。在Windows和Linux上,我发现了这一点,但是在HP_UX机器上运行代码时,它似乎s2和s1是同一个字符串,所以修改s2会改变s1。

听起来很疯狂,有人见过类似的情况吗?


你能发布一个非常简短的重现程序吗?我很难相信如此基础的东西会出现问题。 - Michael Burr
作为一个小问题,你的第二行可以简单地写成 std::string s2(s1); 没有必要创建额外的临时变量。 - luke
5个回答

5
尽管我无法重现OP的确切错误,但我在HP-UX aCC编译器中遇到了类似的错误。我在HP论坛上发布了有关此问题的帖子,并最终得到了HP的回复。基本上,他们的版本3.xx(3.70、3.73、3.67等)的aCC已经破坏了std::string构造。我们不得不转向6.xx版本的编译器。当时我们遇到的问题是,在PA-RISC机器上没有可用的6.xx编译器,只有Itanium。我相信,一个适用于PA-RISC的6.xx编译器在2007年9月发布。

导致问题的代码如下:

#include <iostream>
#include <string>

class S : public std::string  // An extension of std::string
{
public:
  explicit S(const char* s)
    : std::string(s)
  {
  }
};

class N     // Wraps an int
{
public:
  explicit N(int n)
    : _n(n)
  {}
  operator S() const   // Converts to a string extension
  {
    return _n == 0 ? S("zero") : (_n == 1 ? S("one") : S("other"));
  }
private:
  int _n;
};

int main(int, char**)
{
  N n0 = N(0);
  N n1 = N(1);

  std::string zero = n0;
  std::cout << "zero = " << zero << std::endl;
  std::string one = n1;
  std::cout << "zero = " << zero
            << ", one = " << one << std::endl;

  return 0;
}

这是打印输出的内容:
zero = zero
zero = one, one = one

换句话说,由n1构造字符串one时,会完全覆盖另一个字符串(字符串zero)。
注:
要查看编译器版本,请键入"aCC -V"
要查看机器类型,请键入"uname -m"(9000/800 ==> PA-RISC, ia64 ==> Itanium)

3

这一定是一个bug。std::string可能使用引用计数的字符串实现,但一旦它被更改,它应该“分叉”字符串。


1

这两个字符串实际上是否不同,或者您使用其他比较方式(例如c_str()返回的地址)?

一些string的实现在进行复制时并不会复制整个字符串,以加快长字符串的复制速度。如果您尝试对其中任何一个进行更改,则实现应该会复制该字符串并进行适当的更改(理想情况下作为同一操作的一部分)。


1

这肯定是一个缺陷。这个例子是从C++标准中直接摘录的:

string s1("abc");
string::iterator i = s1.begin();
string s2 = s1;
*i = ’a’;  // Must modify only s1

1

这对我来说肯定是个bug。有其他人也能在HP/UX上重现这个问题吗?

你的意思是这个程序在两行上显示相同的文本?

#include <stdio.h>
#include <string>

int main () 
{
    std::string s1 = "hello"; 
    std::string s2 = std::string(s1);   // note: std::string s2( s1); would reduce the number of copy ctor calls

    s2.append( ", world");

    printf( "%s\n", s1.c_str());
    printf( "%s\n", s2.c_str());
}

我尝试在HP-UX上使用HP的aCC编译器版本3.67进行复现。它可以正常工作。然而,我遇到了aCC编译器字符串构造方面的严重问题。我将创建一个单独的帖子来讨论这个问题。 - Andrew Stein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接