【问题标题】:C - fgets mysteriously causes segfault when using char arraysC - fgets 在使用 char 数组时神秘地导致段错误
【发布时间】:2025-12-20 15:05:07
【问题描述】:

我似乎有一些与此类似的问题,但是我以一种非常直接的方式提问,所以希望我能很好地解释到底发生了什么。

看看这个非常简单的程序:

int main()
{
    char* a;
    a[200];
    fgets(a, 200, stdin);

    char* b;
    b[200];
    fgets(b, 200, stdin); // Seg fault occurs once I press enter

    return 0;
};

如您所见,“a”部分运行良好。但是部分“b”段错误。怎么回事?

【问题讨论】:

  • a[200]; 导致undefined behaviour
  • 这并不神秘。没有学习基本的 C 是问题所在。 char* a; a[200]; --> char a[200]char* b; b[200]; --> char b[200]
  • @M.M 但是为什么它是未定义的行为?
  • @SanchkeDellowar:这是未定义的行为,因为变量achar *(这就是char *a; 的含义)。指针没有初始化程序,因此指针的任何取消引用都会导致 UB(未定义的行为)。 a[200]; 取消引用未初始化的指针;幸运的是,编译器可能会优化它。您需要 char a[200]; 处于已定义行为的范围内(b 也是如此)。对fgets() 的调用同样是UB。不幸的是代码没有早点崩溃,但未定义的行为很有趣——任何事情都有可能发生,没关系!
  • @SanchkeDellowar a 没有指向任何地方,所以你不能取消引用它(即查找它指向的内存)

标签: c segmentation-fault fgets


【解决方案1】:

嗯,这是基础知识。段错误意味着您正在使用您无权访问的内存。

int main()
{
    char* a; // Create a pointer (a pointer can only contains an address (int size)
    a[200]; // Trying to access to the byt 200 of your pointer but basicaly do nothing. You are suppose to have a segfault here

    fgets(a, 200, stdin); // store your stdin into &a (you may have a segfault here too)

    return 0;
};

取决于很多事情,有时它可能会失败,有时不会。但是你在这里做错了什么。 你必须设法解决这个问题。首先使用一个简单的数组char

#include <stdio.h> /* for stdin */
#include <stdlib.h> /* for malloc(3) */
#include <string.h> /* for strlen(3) */
#include <unistd.h> /* for write(2) */

int main()
{
     char str[200];
     fgets(str, sizeof str, stdin);

     write(1, str, strlen(str)); /* you can receive less than the 200 chars */

     return (0);
}

或者如果你想继续使用指针

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

int main()
{
     const size_t sz = 200;
     char* str;
     str = malloc(sz);

     fgets(str, sz, stdin);

     write(1, str, strlen(str));
}

但无论如何,你的错误是由于缺乏关于 C 中的指针和内存的知识。

祝你好运,

【讨论】:

  • 如果代码要使用malloc(),使用前应严格检查返回值。对write() 的调用很神秘——它将malloc() 提供的未初始化数据写入标准输出。可能最好删掉,或者改成memset()
  • @JonathanLeffler,你是对的,但是没有一个程序会因为malloc(200);而失败:)