c - 使用 fgets 将数据读入未初始化的 char 指针变量会在第二次读取时崩溃

标签 c pointers undefined-behavior fgets

我知道我们不能使用 fgets 将数据读入未初始化的 char 指针。在 stackoverflow 上有很多与这一点相关的问题。所有答案都指向一个事实,即您不能将数据加载到未初始化的指针变量中。

第一个代码片段中显示的程序能够使用 fgets 填充第一个未初始化的字符指针 (*str2),但是在尝试将数据读入第二个未初始化的字符指针 (*str3) 时崩溃。

我可以使用传统方法让它工作,比如在填充之前预先将内存分配给指针(如下面的第二个代码片段所示)。我的问题是为什么它对第一个变量有效但对第二个变量无效?

问题代码

#include <stdio.h>

int main()
{
    char str1[100], *str2, *str3;
    // Prints fine

    printf("First String: ");
    fgets(str1, 20, stdin);
    printf("%s", str1);

    // Prints fine      
    printf("Second String: ");
    fgets(str2, 20, stdin);
    printf("%s", str2);

    // Program crashes on this input
    printf("Third String: ");
    fgets(str3, 20, stdin);
    printf("%s", str3);

    return 0;

}

工作代码

#include <stdio.h>

int main()
{
    char str1[100], str2[20], str3[20];
    printf("First String: ");
    fgets(str1, 20, stdin);
    printf("%s", str1);

    printf("Second String: ");
    fgets(str2, 20, stdin);
    printf("%s", str2);

    printf("Third String: ");
    fgets(str3, 20, stdin);
    printf("%s", str3);

    return 0;

}

最佳答案

在你的情况下

// Prints fine      
printf("Second String: ");
fgets(str2, 20, stdin);
printf("%s", str2);

包含对未初始化指针的写入,其中包含不确定的值,这意味着它调用 undefined behavior .

一旦您的程序具有 UB,就没有任何保证。拥有 UB 的副作用之一是显示为“(异常)正常工作”,并且也不能保证“崩溃”或段错误。就是这样,未定义。

故事的寓意:不要试图对从包含未定义行为的程序中获得的输出进行推理。

关于c - 使用 fgets 将数据读入未初始化的 char 指针变量会在第二次读取时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55923967/

相关文章:

c++ - 为什么 printf ("%f",0);给出未定义的行为?

c - 使用 libgda-ui 调用 row-activated

c++ - 继承和指向 protected 成员的指针

c - 程序有效性;循环内定义的变量的生命周期和范围

c++ - 尽管更改了字符串,但我的字符串返回了某个数字

c - 在 C 中重新解释内存的正确方法是什么?

c++ - macOS - 读取其他应用程序库代码的一部分并将其反汇编以获取偏移量

c - 带有基本参数的 strtod

c - 我的 for 循环有什么问题?

c - 使用 scanf() 的段错误