Sta*_*ver 1 c pointers fgets undefined-behavior
我知道我们无法使用fgets将数据读取到未初始化的char指针中。关于堆栈溢出的这一点,有很多问题。所有答案都表明您无法将数据加载到未初始化的指针变量中。
第一个代码片段中所示的程序能够使用fgets填充第一个未初始化的char指针(* str2),但是在尝试将数据读取到第二个未初始化的char指针(* 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;
}
Run Code Online (Sandbox Code Playgroud)
工作守则
#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;
}
Run Code Online (Sandbox Code Playgroud)
就你而言
// Prints fine
printf("Second String: ");
fgets(str2, 20, stdin);
printf("%s", str2);
Run Code Online (Sandbox Code Playgroud)
包含对未初始化指针的写入,该指针包含不确定的值,这意味着它将调用未定义的行为。
一旦您的程序具有UB,就无法保证。拥有UB的副作用之一是表现为“正常(正常)工作”,也不保证“崩溃”或分段错误。只是,未定义。
故事的寓意:不要试图对包含未定义行为的程序的输出进行推理。