【问题标题】:C: Segmentation Fault while using printfC:使用 printf 时出现分段错误
【发布时间】:2011-02-27 21:44:08
【问题描述】:

这个可能很简单,但我似乎无法让它工作。

我有这个非常简单的 sn-p 代码:

#include <stdio.h>
#include <string.h>

int main(void)
{

  char buf[100];
  char *p = buf;

  strcpy(p, "Test string");

  printf("%s\n", *p);

}

当我运行它时会导致分段错误。 GDB 输出:

Program received signal SIGSEGV, Segmentation fault.
0xb76af3b3 in strlen () from /lib/i686/cmov/libc.so.6

但我还是不明白。

我们将不胜感激,谢谢。

【问题讨论】:

  • 您可以查看 GCC 警告以了解问题所在:test.c:In function 'main': test.c:12: warning: format '%s' expects type ' char *',但参数 2 的类型为 'int'
  • 很有趣,我没有收到警告信息,如果我收到了,我可能会为每个人节省一些时间,包括我自己 :)
  • 您可能需要确保使用 -Wall 编译器标志以确保不会错过警告。

标签: c pointers printf segmentation-fault


【解决方案1】:

当你写作时

printf("%s\n", *p);

*p 将是 p[0] 的值,它是一个字符。然而, printf 正在寻找一个字符数组,从而导致它出现段错误。请记住,在 C 中,字符串只是字符数组,而数组实际上是指向第一个元素的指针,这就是您不需要取消引用的原因。

要解决此问题,请删除 * 以获取:

printf("%s\n", p);

【讨论】:

    【解决方案2】:

    你正在向 printf 传递一个字符;你应该传递指针。

    char buf[100];
    char *p = buf;
    
    strcpy(p, "Test string");
    
    printf("%s\n", p);     // p, not *p
    

    【讨论】:

    • 啊,是的。当我尊重 p 时,我得到一个字符,因此 printf 的混乱。这听起来对吗?谢谢。
    • 当您传递 *p 时,您只传递了单个字符的值。当您传递p 时,您传递的是指向字符串中第一个字符的指针,因此 printf 可以访问字符串的其余部分。
    【解决方案3】:

    使用这个:

    printf("%s\n", p);
    

    用“p”代替“*p”

    【讨论】:

    • 感谢修复 user358443
    【解决方案4】:

    替换

    printf("%s\n", *p);
    

    printf("%s\n", p);
    

    当你使用%s 时,printf 期望你传递一个char*。你传递的是char

    【讨论】:

    • 嗨,埃里克,谢谢 - 尽管我不明白为什么,但它已修复。我们不应该推迟指针来获取内容吗?
    • @Hamza - 仅当您想打印单个字符时。如果要打印整个字符串,则需要传递指针以便 printf 可以访问它。否则它只有你传递给它的字符(而不是字符串的其余部分)。这更有意义?
    • 这就是我正在寻找的解释,非常感谢!在使用高级语言一段时间后忘记这些原则是多么容易令人着迷:)
    • @Hamza :如果您使用 printf("%c\n", *p),您的行将正常工作并打印一个字符
    【解决方案5】:

    只需传递字符串(指针):

    printf("%s\n", p);
    

    如果要打印第一个字符,则:

    printf("%c\n", *p);
    

    【讨论】:

    • 感谢 AraK 的解释。
    【解决方案6】:

    %s 导致 printf() 取消引用 *p。假设字符串是“测试字符串”。 然后在我的 Solaris sparc 盒子上:(在测试程序中)p 将“瞄准”地址 0x54657374。该特定地址成为您的进程空间一部分的概率几乎为零。

    这就是导致 SIGSEGV 信号(segfault)的原因。

    【讨论】:

      猜你喜欢
      • 2018-06-06
      • 1970-01-01
      • 2015-04-23
      • 1970-01-01
      • 2013-10-12
      • 2021-10-16
      • 2011-12-23
      • 2020-05-29
      • 1970-01-01
      相关资源
      最近更新 更多