【问题标题】:printf("%s\n",str); gives segmentation fault but printf("%s",str); don't, where "str" is a string pointerprintf("%s\n",str);给出分段错误但 printf("%s",str);不要,其中“str”是一个字符串指针
【发布时间】:2015-10-21 20:23:42
【问题描述】:

当我尝试运行以下代码时:

#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]);
}

它给了我输出:

heyhellohow(null)(null)(null)(null)(null)(null)(null)

而当我在 printf 语句中插入 '\n' 时:

#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]);
}

它给了我以下输出:

hey
hello
how  
Segmentation fault

我为此尝试阅读在线材料,发现这是因为格式说明符并由编译器自动将 printf 转换为 putsputs > 无法识别“%s\n”,但我还是无法理解。谁能用简单的术语解释一下。

【问题讨论】:

    标签: c string pointers printf


    【解决方案1】:

    prinf() 中为%s 格式说明符传递空指针是未定义的行为。在一种情况下,运行时试图表现得很好,并在这种情况下显示“(null)”。在另一种情况下,未定义的行为是崩溃。

    造成这种差异的一个可能原因是编译器工具链有时会将printf("%s\n", xxx) 转换为等效的puts(xxx)(GCC 在很多情况下肯定会这样做)。我猜puts() 对你的空指针不太好。

    就我个人而言,我喜欢"%s" 将空指针显示为“(null)” - 它在添加一些快速-n-dirty 调试日志记录时更加方便。但是,如果你这样做了,你就不会在程序崩溃时抱怨,所以你不应该依赖它来做其他事情。

    【讨论】:

    • 否 - 如果它们是恰好指向内容为 "(null)" 的内存的指针,那么在使用 printf("%s\n",a[i]) 时不会发生崩溃。 a[] 的声明有一个初始化器,它将所有未显式初始化的元素设置为 0。 "(null)" 显示的是 printf() 专门处理空字符串指针。
    【解决方案2】:

    您正在声明一个包含 10 个 char 指针的数组。赋值a[0] = "hey",导致指针 a[0] 指向存储在只读内存中的字符串文字“hey”,而您丢失了字符串文字“hi”。

    分段错误是由于在循环中将空指针传递给函数 printf() 引起的,超出了第三个元素。这称为未定义行为。

    【讨论】:

      猜你喜欢
      • 2016-07-20
      • 1970-01-01
      • 2022-12-10
      • 2015-02-15
      • 1970-01-01
      • 2021-06-22
      • 1970-01-01
      • 2016-04-14
      • 2018-06-06
      相关资源
      最近更新 更多