2016-07-22 16 views
-2

在最簡單的形式程序是爲什麼此C程序不會導致字母數字值出現分段錯誤?

int main(){ 
    int x; 
    scanf("%d",x); 
} 

當我們給這個程序的任何數值輸入它無法通過產生段錯誤信號,這是我們應該期待什麼。

但是,如果我們改爲給它任何字母數字值,它不會失敗。

發生這種行爲的scanf是怎麼回事?

這是從GDB回溯與數值運行它時:

(gdb) bt 

#0 0x00000034e7456ed0 in _IO_vfscanf_internal() from /lib64/libc.so.6 

#1 0x00000034e74646cd in __isoc99_scanf() from /lib64/libc.so.6 

#2 0x0000000000400553 in main() 

那麼爲什麼不失敗像「一」或「dfgb」任何字母數字值?

+4

您試圖在此推理* undefined behavior *。在這種特定情況下,可能是因爲輸入與格式字符串不匹配,所以'scanf'甚至不會嘗試訪問第二個參數。但我不會依賴它。 「 –

+4

」如果輸入流中的某個字符與格式字符串衝突,則函數結束,並以'匹配'失敗結束。衝突字符留在輸入流中,就好像它沒有被讀取一樣。您的字母輸入無法匹配預期的十進制格式,因此'scanf()'退出時不會嘗試向錯誤的「地址」寫入任何內容。 –

+0

不贊同「當我們給這個程序任何數字值作爲輸入時,它會產生一個段錯誤信號,這是我們應該期待的。」。使用此代碼,提供數字輸入會導致未定義的行爲,而不一定是seg故障。 Seg是一種可能的期望,但不是唯一的期望。 – chux

回答

5

標準的第7.21.6.2/10說:

如果輸入的產品不匹配的序列中, 指令的執行失敗:這種情況是匹配失敗。

和7.21.6.2/4:

fscanf函數執行依次格式的每個指令。 當所有指令都被執行或指令失敗時(如下面詳述的 ),函數返回。故障被描述爲輸入 故障(由於發生編碼錯誤或輸入字符不可用)或匹配故障(由於 不適當的輸入)。

作爲輸入提供沒有好分析的整數,scanf剛剛返回0指示沒有轉換從輸入製成,不要試圖取消引用您傳遞的參數。

這個答案被編輯引用關於這一點的標準,感謝@Zwol

+3

我不認爲這是_is_未定義的行爲。 [N1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf)第7.21.6.2節是(f)scanf的規範。轉換指令的行爲被描述爲一步一步的算法,並且在我看來,實現是必需的**而不是**來訪問「尚未在格式參數之後的第一個參數所指向的對象收到轉換結果「,除非轉換成功。由於這是一個可變參數函數,因此沒有其他規定強制要求每個變量參數都是一個指針。 – zwol

+0

@zwol沒錯,7.21.6.2/10很清楚,需要編輯,謝謝。 –

相關問題