对此的任何想法将不胜感激:
std::string s1 = "hello";
std::string s2 = std::string(s1);
我现在希望这两个字符串是独立的,即我可以将“, world”附加到 s2 并且 s1 仍然会读取“hello”。这是我在 windows 和 linux 上找到的,但在 HP_UX 机器上运行代码似乎 s2 和 s1 是同一个字符串,所以修改 s2 会更改 s1。
这听起来绝对疯狂吗,有人见过类似的东西吗?
虽然我无法重现 OP 的确切错误,但我在 HP-UX aCC 编译器中遇到了类似的错误。我把它贴在了惠普的板上,最终得到了惠普的回应。基本上,他们的 aCC 版本 3.xx(3.70、3.73、3.67 等)搞砸了 std::string 的构造。我们不得不迁移到编译器的 6.xx 版本。我们当时遇到的问题是,没有可用于 PA-RISC 机器的 6.xx 编译器,只有 Itanium。我相信 2007 年 9 月发布了用于 PA-RISC 的 6.xx 编译器。
给出问题的代码是:
#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;
}
这是打印:
零 = 零零
= 一,一 = 一
换句话说,从 n1 构造字符串 1 完全破坏了另一个字符串(字符串 0)。
注意:
要查看编译器的版本,请键入“aCC -V”
要查看机器类型,请键入“uname -m”(9000/800 ==> PA-RISC,ia64 ==> Itanium)
这一定是个bug。std::string 可以将引用计数字符串作为其实现,但是一旦它被更改,它应该“分叉”字符串。
这对我来说听起来确实是个错误。可以访问 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());
}
这两个字符串的实际变化是否不同,或者您是否使用了其他比较(例如 c_str() 返回的地址)?
字符串的某些实现在进行复制时不会复制整个字符串,以加快复制长字符串的速度。如果您尝试对其中任何一个进行更改,则实现应该复制字符串并进行适当的更改(理想情况下作为同一操作的一部分)。
这肯定是一个缺陷。此示例逐字地来自 C++ 标准:
string s1("abc");
string::iterator i = s1.begin();
string s2 = s1;
*i = ’a’; // Must modify only s1