C 带有换行符的printf导致奇怪的seg。过错

C 带有换行符的printf导致奇怪的seg。过错,c,linux,C,Linux,在执行此代码段时,我观察到一种奇怪的行为 #include <stdio.h> void main() { char *a[10] = {"hi", "hello", "how"}; int i = 0, j = 0; for (i = 0;i < 10; i++) printf("%s\n", a[i]); } 但是如果在printf语句中用空格字符替换“\n”字符,则没有seg。错误来了 hi hello how (nul

在执行此代码段时,我观察到一种奇怪的行为

#include <stdio.h>

void main()
{
    char *a[10] = {"hi", "hello", "how"};
    int i = 0, j = 0;
    for (i = 0;i < 10; i++)
            printf("%s\n", a[i]);
}
但是如果在printf语句中用空格字符替换“\n”字符,则没有seg。错误来了

hi hello how (null) (null) (null) (null) (null) (null) (null) 
我在Ubuntu上使用gcc v4.4.3。
换行符如何导致seg。printf中的错误?

您所拥有的是。您有一个包含十个指向
char
的指针的数组,但只有前三个指针实际指向某个有效的对象,而其余的指针是
NULL
指针。取消引用
NULL
指针会导致未定义的行为,该行为有时会起作用,有时会使程序崩溃。

仅初始化数组中的前三项(通过三个字符串)。在尝试访问其他七个char*指针之前,您需要初始化它们。

您只初始化了10个数组成员中的3个。访问未初始化指针的行为未定义。有时崩溃,有时不崩溃。

您有未定义的行为。您只初始化了3个指针,其余指针指向
NULL
。当您试图打印
NULL
指针时,会导致未定义的行为

尝试以下方法,它将为您工作

void main()
{
char a[10][10] = {"hi", "hello", "how"}; // here statically i am allocating array. 
// First three elements are initialized and the remaining elements contains null.
int i = 0, j = 0;
for (i = 0;i < 10; i++)
        printf("%s\n", a[i]);
}
void main()
{
char a[10][10]={“hi”,“hello”,“how”};//这里静态分配数组。
//前三个元素已初始化,其余元素包含null。
int i=0,j=0;
对于(i=0;i<10;i++)
printf(“%s\n”,a[i]);
}

行为上的差异是由于gcc将
printf(“%s\n”,…)
优化为
put(…)
,这在功能上是相同的,除非字符串为
NULL


在第二种情况下,gcc无法优化调用,从而导致不同的输出。

我不明白如何将其描述为“奇怪”…对于(I=0;I<3;I++)的
如何呢
,因为您有一个指向3个数组的指针?当数组或结构从括号内的初始值设定项初始化时,任何没有初始值设定项的成员都会被初始化,就像给定了
0
一样。因此其他指针被初始化为空指针。@kristianp uninitialized不等于空。事实上,调试中的MSVC经常将未初始化的值“初始化”为0xCCCC。如果我错了,请纠正我的错误,但是C标准不要求仍定义带NULL的%s行为吗?@DrewMcGowen刚刚检查了一下以确定,C11规范没有对此做任何说明。
void main()
{
char a[10][10] = {"hi", "hello", "how"}; // here statically i am allocating array. 
// First three elements are initialized and the remaining elements contains null.
int i = 0, j = 0;
for (i = 0;i < 10; i++)
        printf("%s\n", a[i]);
}