【问题标题】:Arrays Stack Overflow [closed]数组堆栈溢出[关闭]
【发布时间】:2012-04-14 15:42:40
【问题描述】:
    #include
    int main(void)
    {
        char str[100]="88888888888888";
        char t[20]="";
        gets(t);
        puts(str);
        puts(t);
        return 0;
    }

第一行

555555555555555555555555555555555

被放进去。

为什么str55555555555?为什么str 不是8888888888888888855555555555588888

【问题讨论】:

标签: c


【解决方案1】:

您覆盖了t 缓冲区,并到达了str 缓冲区,其中输入的其余部分和空终止符已设置。而puts 只打印到空终止符为止。

差不多是这样的:

[ t (20)             ][str(100)                                 ]
 55555555555555555555  5555555555555\0

请注意,虽然 t 被声明为 char[20],但当您打印它时,您会得到完整的输入(超过 20 个),因为 puts 会在空终止符处停止(再次)。

顺便说一句,这是缓冲区溢出,不是堆栈溢出,但此代码也可能发生堆栈溢出。

【讨论】:

    【解决方案2】:

    正如 Binyamin 所说,这是由于输入字符串太长而触发的溢出引起的。然而,这有点随机——有时两个内存分配会紧挨着发生,字符串会扩展到相邻的变量,有时可能不会发生。

    我建议你为这种溢出设置保护条件。

    如果你看到getsdocumentation

    请注意,gets 的行为与 fgets 对 stdin 的行为不完全相同 参数:首先,结束换行符不包含在 get while 与 fgets 它是。其次,gets 不允许你指定 读取字符数的限制,所以你必须小心 使用 str 指向的数组的大小来避免缓冲区溢出。

    如果您不知道大小,最好使用fgets,因为它更安全(虽然有点慢)。

    【讨论】:

    • 这两个变量将在堆栈上,而不是堆上 - 它们彼此的接近程度将在编译时确定(在调试模式下编译可能会在它们之间插入填充,使用优化编译可能会重新排序他们...),所以我不会称之为随机
    • @DCoder 我不太明白你的意思。一旦您提到它们在堆栈中的位置取决于编译参数。我也知道,如果引入新变量,它们可能会将变量分开。上下文中的随机应理解为:“取决于许多情况,难以确定性地预测”。
    • 我只是想说位置是在编译时确定的,而不是在运行时确定的,所以简单地再次运行程序不会改变分配发生的位置。
    • @DCoder 我从来没有提到它会在同一个程序的多次运行中改变......
    【解决方案3】:

    当您输入超过 20 个5s 的字符串时,它会超出分配给t 的缓冲区并延伸到分配给str 的缓冲区。

    然后它会显示str 的内容,这是您输入的字符串,从第 21 个字符开始。

    最后,它显示t 的内容,但由于该字符串不以空字符结尾,它会继续显示内存(分配给str 的缓冲区),直到它遇到空字符5s.

    【讨论】:

      【解决方案4】:

      为了避免这些分配重叠问题,您可以尝试这种替代方法,如果我没记错的话,分配会在运行时进行:

          #include <iostream>
      
          int main(void)
          {
            char *str;
            char *t;
            str = new char(100);
            str = (char*)"88888888888888";
            t = new char(20);
            std::cin >> t;
            puts(str);
            puts(t);
            return 0;
          }
      

      【讨论】:

        猜你喜欢
        • 2012-06-02
        • 2011-07-30
        • 1970-01-01
        • 1970-01-01
        • 2016-06-02
        • 2014-07-20
        • 2016-05-06
        • 2019-05-18
        • 1970-01-01
        相关资源
        最近更新 更多