c - 是否有可能以某种方式使该程序崩溃?

标签 c arrays string memory crash

我目前正在大学的一门类(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/

相关文章:

c - 如果我说 calloc(1000, 23),那么 23 "round up"会变成 24 吗?还是到32?

arrays - 如何为包含一些固定值并可能具有其他附加值的数组字符串创建数组 json 模式

python - 如何检查子字符串是否为ascii+latin字符并用空格填充ascii/latin字符子字符串?

c# - 编写正则表达式以搜索子字符串 C#

c# - 检查日期字符串是什么区域性,然后将其转换为 DateTime

c++ - 如何找出哪个嵌套for循环更好?

c - C 中数组存储在哪里?

arrays - xcode、ios8、swift、文件和数组

java - 快速排序 - 线程 "main"java.lang.ArrayIndexOutOfBoundsException : -1 中的异常

c++ - 如何合并(混合)两个立体声 mp3 音频文件