[英]Runtime dependency for std::string concatenation
std::string sAttr("");
sAttr = sAttr+VAL_TAG_OPEN+sVal->c_str()+VAL_TAG_CLOSE;
否則在我定義的代碼中
const char VAL_TAG_OPEN[] = "<value>";
sVal
是一個從字符串指針數組中檢索的變量。 這在大多數系統,Windows和Linux中都能正常工作。 然而,在一個客戶站點,我認為我們已經在哪個版本的linux上進行了一些廣泛的測試,產生一個結果,好像我從未使用過VAL_TAG_OPEN
和VAL_TAG_CLOSE
。 我收到的結果是
sAttr = sAttr+sVal->c_str();
這是怎么回事 ?。 std :: string連接是否因運行時而異?
為什么->c_str()
? 如果sVal
是std::string
,請嘗試刪除此調用。 請記住,評估的順序是未定義的,因此您最終可能會添加指針而不是連接字符串,因為VAL_TAG_OPEN
, sVal->c_str()
和VAL_TAG_CLOSE
都是純C字符串。 我建議你使用加法賦值運算符+=
,例如:
sAttr += VAL_TAG_OPEN;
sAttr += *sVal; /* sVal->c_str() ? */
sAttr += VAL_TAG_CLOSE;
(無論如何應該更快)。
不,std :: string連接絕對不應該依賴於運行時,但不知何故VAL_TAG_OPEN
和VAL_TAG_CLOSE
似乎是空字符串。
我猜你在某處有某種緩沖區溢出或無效指針運算,所以你的程序會覆蓋包含那些“常量”值的內存。 無論你的記憶最終存在,確實是運行時(因此OS版本)。 過去通過切換編譯器或優化器選項,我被類似的東西困住了。
正如你提到在原始數組中保留std :: string實例的原始指針一樣,這樣的錯誤確實不是不可能的,但可能很難檢測,因為使用DEBUG構建不會給你任何迭代器檢查所有這些全部到好東西......祝你好運。
我並不認為導致問題的評估順序。 它是因為開頭和結尾的常量字符數組
const char VAL_TAG_OPEN[] = "<value>";
const char VAL_TAG_CLOSE[] = "</value>"
連接運算符認為VAL_TAG_OPN和VAL_TAG_CLOSE不是空終止符字符串。 因此優化器只是忽略了他們認為它是垃圾。
sAttr += std::string(VAL_TAG_OPEN);
sAttr += *sVal;
sAttr += std::string(VAL_TAG_CLOSE);
這確實解決了它。
sAttr = sAttr+VAL_TAG_OPEN+sVal->c_str()+VAL_TAG_CLOSE;
就像fbonnet所說,這是評估問題的一個順序。
如果該行從左到右嚴格評估,那么每次添加的結果都是一個std :: string對象,它有一個運算符重載以便添加,並且事情按預期工作。
如果它沒有從左到右進行評估,那么你最終會將指針添加到一起,誰知道會給你帶來什么。
避免使用此構造,只需在std :: string上使用+ =運算符即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.