有這方面的想法,將不勝感激:C++的std :: string構造
std::string s1 = "hello";
std::string s2 = std::string(s1);
我現在所期待這兩個字符串是獨立的,也就是說我可以追加「世界」到S2和S1仍然會讀「你好」。這是我在windows和linux上找到的,但是在HP_UX機器上運行代碼,看起來s2和s1是相同的字符串,所以修改s2會改變s1。
聽起來這絕對是瘋狂的,任何人都看過類似的東西嗎?
有這方面的想法,將不勝感激:C++的std :: string構造
std::string s1 = "hello";
std::string s2 = std::string(s1);
我現在所期待這兩個字符串是獨立的,也就是說我可以追加「世界」到S2和S1仍然會讀「你好」。這是我在windows和linux上找到的,但是在HP_UX機器上運行代碼,看起來s2和s1是相同的字符串,所以修改s2會改變s1。
聽起來這絕對是瘋狂的,任何人都看過類似的東西嗎?
這必須是一個錯誤。 std :: string可以將引用計數的字符串作爲其實現,但一旦它被更改,它應該「分叉」字符串。
這聽起來像是一個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編譯器字符串構造的嚴重問題。我將爲此創建一個單獨的帖子。 – 2008-10-10 15:11:25
這兩個字符串實際上是否改變了不同,或者您是否使用其他比較(例如c_str()返回的地址)?
某些字符串的實現在複製時不會複製整個字符串,以加速長字符串的複製。如果您試圖對其中一個進行更改,那麼實現應該複製該字符串並進行適當的更改(理想情況下作爲同一操作的一部分)。
這肯定會是一個缺陷。這個例子是從C++標準逐字:
string s1("abc");
string::iterator i = s1.begin();
string s2 = s1;
*i = ’a’; // Must modify only s1
雖然我不能重現OP的確切的錯誤,我遇到了類似的錯誤在HP-UX ACC編譯器來了。我在HP boards上發佈了它,最終得到了惠普的迴應。基本上他們的3.xx版本(3.70,3.73,3.67等)的aCC已經搞砸了std :: string構造。我們必須轉向編譯器的6.xx版本。我們當時遇到的問題是沒有可用於PA-RISC機器的6.xx編譯器,而只有Itanium。我相信,一個6.XX編譯器被公佈爲PA-RISC於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;
}
這是印刷:
零=零
零=一個,一個等於一
換句話說串的一個從n1的建設完全重挫另一個字符串(字符串零)。
注意:
要查看編譯器的版本,類型 「ACC -V」
要查看機器的類型,類型 「UNAME -m」(9000/800 ==> PA-RISC,IA64 = =>安騰)
你能發佈一個很短的repro程序嗎?我很難相信那些基本的東西已經被打破了。 – 2008-10-09 23:06:40
作爲一個nit pick,你的第二行可以簡單地寫成std :: string s2(s1);沒有理由創建額外的臨時設備。 – luke 2008-10-10 12:27:55