为什么用%s打印字符会导致分段错误?

时间:2019-04-04 04:03:34

标签: c segmentation-fault

为什么每次打印带有%s的字符都会出现分段错误?

#include <stdio.h>

int main()
{
  char c = 'a';
  printf("%s",c);
    return 0;
}

如果可能是由于未获得'\ 0'而导致的,除非继续访问只读内存位置,否则它将继续读取,为什么总是这样呢? (因为该代码应该在某处(最有可能)获得\ 0

#include <stdio.h>

int main()
{
  char c[2];
  c[0] = 'a';
  c[1] = 'a'; //skipping '\0'
  printf("%s",c); //aa..(then some random output)
    return 0;
}

对不起,如果这个问题很愚蠢,我只是一个初学者。

3 个答案:

答案 0 :(得分:3)

  

为什么每次打印带有%s的字符都会出现分段错误?

因为%s告诉printf,该参数是字符串的指针,并且因为大多数现代系统都保护低地址存储器免受所有访问(以防止出现诸如避免被发现)

当您将'a'传递给printf时,它会得到一个值0x41ASCII的{​​{1}}代码),解释将该值作为指针,它指向内存的最低页面,该页面由无访问权限保护-> a

答案 1 :(得分:0)

因为%s printf需要一个指向string的指针。 因此,在打印时printf尝试从地址打印c(c的值)存储,这可能是无效的(因为它实际上不是地址),从而导致段错误。

您可以执行printf(“%s”,&c); //这可能会产生一些垃圾值

答案 2 :(得分:0)

这是您打算做的事情

#include <stdio.h>

int main()
{
    char c = 'a';
    printf("%c",c);  /* <<<< use %c instead of %s, read printf(3) */
    return 0;
}

如果您这样做:

#include <stdio.h>

int main()
{
    char c[2];
    c[0] = 'a';
    c[1] = 'a'; //skipping '\0'
    printf("%s",c); //aa..(then some random output)
    return 0;
}

这次,您传递printf()指针(仅将数组名c解释为第一个元素的地址,因此可以使用{{ 1}}格式说明符。这次,缺少printf()使得%s可以继续打印,直到得到\0为止,您可以将代码更改为:

printf()

,您将获得\0作为打印输出。