我目前正在大学的一门类(class)中学习 C。现在我们有一项任务要解决,但我不确定该怎么做。
任务看起来像这样: “是否有可能让这个程序因用户输入而崩溃?如果是这样,请解释这种情况。”
我们得到的程序非常简单,如下所示:
#include <stdio.h> // Include to use printf, scanf
int main()
{
// Define buffers to store user name and password
char username[16];
char password[16];
// Read username and password from user input
printf("Enter your name: ");
scanf("%s", username);
printf("Enter your password: ");
scanf("%s", password);
printf("[SHOUTING OUT LOUD] Hello, %s!\n", username);
return 0;
}
我已经发现,如果您使用超过 15 个字符的用户名,您可以让程序打印出密码。但这显然不是崩溃。 所以我还没有找到使程序崩溃的方法,但不知何故我很确定,有一种方法可以做到这一点。 有人知道吗?
谢谢:)
最佳答案
输入超过 15 个字符的用户名或密码可能使程序崩溃,只是不保证一定会这样。
当您越过数组边界写入时,您会调用 undefined behavior .笼统地说,这意味着您不能对您的程序将做什么做出任何假设。它可能会崩溃,可能会输出奇怪的结果,或者它可能看起来工作正常。
仅仅因为程序可能崩溃并不一定意味着它会。
话虽这么说,考虑到您可能遇到的大多数编译器的工作方式,您输入的字符串越长,崩溃的可能性就越大。
局部变量通常分配在彼此相邻的堆栈上。例如,假设 username
在堆栈中紧接在 password
之前。如果您为用户名输入 20 个字符的名称,它将把过去的 username
写入 password
并且 username
将不包含空终止字节。然后当您输入密码时,它会覆盖用户名前 16 位之后的所有字符。然后当您打印 username
时,您会看到您输入的前 16 位字符,后面是密码。
现在假设您输入 100 个字符作为用户名。这将写入过去的 username
和过去的 password
并且很可能会覆盖 main
的返回地址。然后,当 main
尝试返回时读取了一个虚假地址,并试图跳转到该地址是导致崩溃的原因。
但同样,这完全是系统特定的,并且会根据您放置变量的类型/顺序、调用的函数以及用于编译的优化设置等而有所不同。
关于c - 是否有可能以某种方式使该程序崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62214884/