作者gamerred (game859)
看板EE_DSnP
標題[建議] myStrNCmp in util/myString.cpp
時間Fri Oct 28 08:18:38 2011
第 30 行
...
29
for (
unsigned i =
0; i < l; ++i ) {
30
>> if (!s2[i])
31
return (i < n)?
1:
0;
...
這行應該是要判斷 string s2 有沒有到結尾吧
但是這個用法不對
顯然我們期待在字串結尾處有'\0'字元
但是在我們期待'\0'存在的地方已經超出string的範圍了
string 的 operator[] 是不能dereference超過 size 長度的
如果超出長度 雖然他不會檢查 但是會有潛在的危險
string 的標準中沒有規定必須以結尾字元'\0' 結尾
所以每個library 可能提供不同的實作
即使某些實作版本中真的有'\0'在那個位置
也不該期待在那個地方永遠會有結尾字元
這會降低程式碼的可攜性
請參考 string 的 member function c_str() 還有 data() 和 operator[]
http://www.cplusplus.com/reference/string/string/operator[]/
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.247.241
1F:推 wmin0:有道理 10/28 09:48
3F:→ wmin0:這個似乎保險一點 10/28 09:52
at() 函式確保了安全,但是也犧牲了效率
operator[] 裡面不檢查範圍的原因就是為了速度!
確保範圍的責任就交給程式設計師了
4F:推 vuluy:可是at丟出的exception是什麼意思呢,是會終止程式嗎?? 10/28 09:57
例外處理(exception)是為了處理非正常程序執行時會遇到的狀況
典型的例子就是"除以零例外"(DevideByZeroException)
不過他不是預設的例外之一XD
例外處理將在做適當處理後 1.繼續執行(fault-tolerant) 或
2.終止程式(gracefully degrade)
而不是不負責任的直接呼叫abort()留下爛攤給OS收拾
詳情請參考螞蟻書 exception 章節
5F:推 djshen:把string的字尾改掉 cout string的話會是原本的 但是 10/28 09:57
6F:→ djshen:data()就會連後面的一起印出來 10/28 09:58
嘗試印出未定義記憶體空間是非法的行為
這就像是故意開一個未以'\0'結尾的字元字串 然後印出一樣
而前面第一個狀況是因為 string 內部可以用別的變數來記錄size
如此一來就不需要用到結尾字元來表示字串的結束
7F:→ djshen:at如果超過範圍好像會直接停止耶@@ 10/28 10:11
※ 編輯: gamerred 來自: 140.112.247.241 (10/28 13:20)
※ 編輯: gamerred 來自: 140.112.247.241 (10/28 13:22)
8F:→ djshen:我也是想說用size來看 10/28 13:44
9F:→ djshen:string好像會在後面多留一點空間 所以改那個空間裡的東西 10/28 18:48
10F:→ djshen:然後用data()去access應該不算是去動到未定義空間吧? 10/28 18:50
11F:→ djshen:不過印出string是由size控制而不是'\0'是可以確定的@@ 10/28 18:56
12F:推 ric2k1:Very good point! I should have used s2.size() instead 10/28 19:09
13F:→ ric2k1:of s2[i] to check string end. Will correct this in 10/28 19:09
14F:→ ric2k1:future homework. 這個作業應該沒有影響。 10/28 19:10
15F:→ djshen:發現有些狀況的確會有非法存取的問題.. 10/28 19:46