6

将 NULL 作为参数传递时的行为是strstr什么?

鉴于:

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

情况1: strstr(p, "Hello");

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

案例3: strstr(p, s);

我的理解是,行为是未定义的,由所有 3 种情况的实现决定。

根据 Microsoft Visual Studio 文档,他们执行参数验证并在那里处理。 见备注部分。

我们在 IAR Workbench 上使用 C99。

背景:一些测试人员正在编写单元测试并将 NULL 分配给字符串变量。

4

2 回答 2

4

ISO C 标准说行为是未定义的。

引用N1570,这是 2011 ISO C 标准的草案,第 7.1.4 节:

除非在随后的详细描述中另有明确说明,否则以下每个语句均适用:如果函数的参数具有无效值(例如[...]或空指针[...],则行为是不明确的。

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优化了第二个参数的空字符串的情况。未定义的行为是不需要检测或诊断的错误;作为程序员,首先避免未定义的行为完全是您的责任。

于 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 回答