为什么我在第一个代码中得到分段错误而在第二个代码中没有?

时间:2013-10-18 12:29:18

标签: c++ c pointers segmentation-fault newline

我已经声明了一个包含10个指向字符数组的数组。在10个中我只初始化了3个。 当我在%s之后使用\n打印数组时,它会提供如下输出:

hi
hello
how 
segmentation fault

但如果我不使用\n,那么它会提供如下输出:

hihellohow(null)...(7 times).

有人可以解释一下吗?


代码1

#include <stdio.h>

void main()
{
    char *a[10] = {"hi", "hello", "how"};
    int i = 0, j = 0;

    a[0] = "hey";
    for (i = 0;i < 10; i++)
        printf("%s\n", a[i]);
}

代码2

#include <stdio.h>

void main()
{
    char *a[10] = {"hi", "hello", "how"};
    int i = 0, j = 0;

    a[0] = "hey";
    for (i = 0;i < 10; i++)
        printf("%s", a[i]);
}

3 个答案:

答案 0 :(得分:5)

正如您自己所说,您不会将数组元素初始化超过第三个,因此它们会自动初始化为空指针。尝试打印这些空指针是未定义的行为,因此任何都可能发生(包括第一个示例中的段错误,或者出现,就像在第二个示例中一样)。< / p>

在这两种情况下,您的代码都是错误的,尝试解释为什么会发生随机事件(再次,段错误或似乎工作)是毫无意义的。

答案 1 :(得分:4)

实际上,它可能来自您的编译器。如果您使用GCC,this page会说明printf("%s\n", s)已优化为puts(s)。该页面显示了2004年的错误报告,但我可以在Windows下使用GCC-4.7.2重现该错误。虽然printf具有防止空指针的保护,但puts似乎没有,因此取决于换行符的行为也不同。

然而,正如syam已经说过的那样,将空指针作为字符串给出并不是标准的,并且可能导致任何事情发生。这只是GCC友好,打印(null)而不是简单地崩溃。

答案 2 :(得分:3)

两种情况都不正确,他们试图打印空指针的内容,这没有任何意义。您正在调用任何可能发生的未定义行为。

C标准保证行char *a[10] = {"hi", "hello", "how"};以下列方式初始化:

a[0] -> "hi"
a[1] -> "hello"
a[2] -> "how"
a[3] -> NULL
...
a[9] -> NULL