簡體   English   中英

C ++中的字符串[length()],可以嗎?

[英]string[length()] in C++, is it OK?

我同事的代碼看起來像這樣:

void copy(std::string const& s, char *d) {
  for(int i = 0; i <= s.size(); i++, d++)
    *d = s[i];
}

他的應用程序崩潰,我認為這是因為這個訪問s超出范圍,因為條件應該只到s.size() - 1

但是我旁邊的其他人說過去有人討論這是合法的。 有人可以幫我清楚一下嗎?

讓我們拋開*d無效的可能性,因為這與問題所針對的內容無關:當訪問索引std::string::size()的“元素”時, std::string operator[]()是否具有良好定義的行為std::string::size()

C ++ 03標准具有string::operator[]()的以下描述(21.3.4“ basic_string element access”):

 const_reference operator[](size_type pos) const; reference operator[](size_type pos); 

返回:如果pos < size() ,則返回data()[pos] 否則,如果pos == size() ,則const版本返回charT() 否則,行為未定義。

由於示例代碼中的sconst ,因此行為定義良好, s[s.size()]將返回空字符。 但是,如果s不是const string ,則行為將是未定義的。

C ++ 11補救了const版本的奇數行為,其行為與此邊緣情況下的非const版本不同。 C ++ 11 21.4.5“ basic_string element access”說:

 const_reference operator[](size_type pos) const; reference operator[](size_type pos); 

需要: pos <= size()

返回: *(begin() + pos )如果pos < size() ,否則引用類型為T的對象,其值為charT() ; 參考值不得修改。

因此,對於C ++ 11編譯器,無論string是否為const ,行為都是明確定義的。

與這個問題無關,我發現C ++ 11說“引用的值不會被修改”有點奇怪 - 我不清楚該子句是否僅適用於pos == size() 我很確定有大量的現有代碼可以執行s[i] = some_character; 其中s是非const std:stringi < s.size() 這是不確定的行為嗎? 我懷疑該子句僅適用於特殊情況的charT()對象。

另一個有趣的事情是,兩個標准似乎都不要求為s[s.size()]返回的對象的地址與s[s.size() - 1]返回的對象的地址有任何關系。 換句話說,似乎返回的charT()引用不必與字符串數據的末尾連續。 我懷疑這是為了給實現者提供一個選擇,如果需要,只返回對該Sentinel元素的單個靜態副本的引用(這也解釋了C ++ 11的“不應修改”限制,假設它僅適用於特殊案件)。

cppreference說:

 reference operator[]( size_type pos ); const_reference operator[]( size_type pos ) const; 

如果pos==size()

  • const版本返回對值為CharT()(空字符)的字符的引用。 (直到C ++ 11)
  • 兩個版本都返回對值為CharT()(空字符)的字符的引用。 通過非const引用修改空字符會導致未定義的行為。 (自C ++ 11以來)

只要你不修改空字符就可以了。

如果你想這樣做(你的同事的代碼試圖復制終止\\0 )你可以

  • 使用c_str()
  • 使用帶有i < s.size()的循環,然后手動追加\\0

編輯:
那么,從其他答案判斷,我更傾向於認為Abyx的評論是正確的:數組d可能溢出(或者甚至可能沒有分配)。 先檢查一下。
但是要確保你復制\\0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM