2013-10-25 153 views
5

當NULL作爲strstr中的參數傳遞時的行爲是什麼?什麼是strstr的NULL參數行爲?

考慮:

char * p = NULL; 
char * s = NULL; 

案例1:strstr(p, "Hello");

案例2:strstr("With my dog", p);

案例3:strstr(p, s);

我的理解是,該行爲是不確定的,並留給了所有3例的實施。

根據Microsoft Visual Studio文檔,他們執行參數驗證並在那裏處理它。 See Remarks section.

我們在IAR Workbench上使用C99。

背景:一些測試人員正在編寫單元測試並將NULL賦值給字符串變量。

回答

4

ISO C標準說明行爲未定義。

引用N1570,這是2011年ISO C標準的草案,7.1.4節:

每個下面的語句適用,除非另有在下面的詳細說明明確指出 :如果一個參數到 函數具有無效值(例如[...], 或一個空指針,[...],該行爲是未定義。

strstr在7.24.5.7中的描述表示:

的strstr函數定位串 在第一次出現的指向字符序列的S1(不含 終止空字符)在由s2指向的字符串中。

除了7.1.4中的聲明,它還指出參數必須指向某個字符串(空指針沒有)。

這些語句在C90和C99標準中是相似的,如果不相同的話。

請注意,「未定義的行爲」並不意味着程序一定會崩潰。例如,這個程序:

#include <stdio.h> 
#include <string.h> 
int main(void) { 
    char *p = strstr(NULL, ""); 
    if (p == NULL) { 
     printf("p == NULL\n"); 
    } 
    else { 
     printf("p = %p\n", p); 
    } 
} 

編譯和我的系統上運行時(Linux操作系統,GCC 4.7.2,glibc的2.15)的打印:

p == NULL 

可能是因爲strstr優化空字符串的情況下,爲第二個參數。未定義的行爲是不需要檢測或診斷的錯誤;作爲一名程序員,您完全有責任首先避免未定義的行爲。

1

您幾乎可以預料未定義行爲的崩潰。

的MSFT文件說,對strstr參數:「如果str或strSearch是NULL,無效參數調用處理程序」和「默認無效參數調用沃森崩潰報告,這會導致應用程序崩潰」(http://msdn.microsoft.com/en-us/library/vstudio/ksazx244.aspx) 。

但是,通過使用函數_set_invalid_parameter_handler(至少在MSFT世界中),您可以更改此設置。當調用該函數時,您必須決定如何恢復,以及是否應該通知用戶或程序是否可以繼續。

相關問題