6

のパラメータとして NULL が渡された場合の動作はstrstr?

与えられた:

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

ケース 1: strstr(p, "Hello");

ケース 2: strstr("With my dog", p);

ケース 3: strstr(p, s);

私の理解では、動作は未定義であり、3 つのケースすべての実装に任されています。

Microsoft Visual Studio のドキュメントによると、彼らはパラメーターの検証を実行し、そこで処理します。 備考欄参照。

IAR Workbench で C99 を使用しています。

背景: 一部のテスト関係者は、単体テストを作成し、文字列変数に NULL を割り当てています。

4

2 に答える 2

4

ISO C 標準では、動作は未定義であると規定されています。

2011 ISO C 標準のセクション 7.1.4 のドラフトであるN1570を引用します。

以下の詳細な説明で特に明記されていない限り、次の各ステートメントが適用されます未定義。

strstr7.24.5.7の説明には次のように書かれています。

strstr関数は、 s2 が指す文字列内の一連の文字 (終端のヌル文字を除く) が、 s1 が指す文字列内で最初に出現する位置を特定ます

これは、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、2 番目の引数の空の文字列の大文字と小文字を最適化するためです。未定義の動作は、検出または診断する必要のないエラーです。そもそも未定義の動作を回避するのは、プログラマーとしてのあなたの責任です。

于 2013-10-25T01:57:42.787 に答える
1

未定義の動作によるクラッシュはほぼ予想できます。

MSFT のドキュメントには、strstrパラメーターについて次のように記載されています。「str または strSearch が NULL の場合、無効なパラメーター ハンドラーが呼び出されます」および「デフォルトの無効なパラメーターによって Watson クラッシュ レポートが呼び出され、アプリケーションがクラッシュします」( http://msdn.microsoft .com/en-us/library/vstudio/ksazx244.aspx )。

ただし、関数 _set_invalid_parameter_handler を使用してこれを変更できます (少なくとも MSFT の世界では)。その関数が呼び出されたら、回復方法と、ユーザーに通知するか、プログラムを続行できるかを決定する必要があります。

于 2013-10-25T01:32:37.223 に答える