【问题标题】:Error: Stack around the variable 'string' was corrupted错误:变量“字符串”周围的堆栈已损坏
【发布时间】:2011-06-06 09:07:10
【问题描述】:

我对下面的代码有一个小问题。这是一个简单的程序,它读取 2 个 char 和一个 int 数组。然后它将所有内容存储到另一个字符串中并打印出来。

#include <stdio.h>
#include <string.h>

int main ()

{
    char string [50];
    char first [11]; 
    char last [16];
    int age = 0;


    printf("Please type in your first name: ");
        scanf("%s", first); 

    printf("Please type in your last name: ");
        scanf("%s", last); 

    printf("Please type in your age: ");
        scanf("%d", &age); 

    sprintf(string, "Your name is %s %s and you are %d years old.", first, last, age);
        puts(string);

    getchar();
    getchar();

    return 0;
}

现在程序运行正常,但是当我关闭它时,我收到以下错误: 运行时检查失败 #2 - 变量“字符串”周围的堆栈已损坏。 这有点令人困惑,我无法弄清楚问题出在哪里。我会很感激 任何建议。

【问题讨论】:

  • 不相关,但如果你有 C99(或对它的某些部分有保证),你应该改用 snprintf 来防止此类问题的发生。

标签: c


【解决方案1】:

您在“字符串”中写入的字符数超过了分配的空间(即超过 50 个)

在您添加第一个、最后一个和年龄的值之前,"Your name is %s %s and you are %d years old." 中有 37 个字符。这三个变量只剩下 13 个字符。所以它会溢出到堆栈上的变量“字符串”之后声明的其他变量中。

正如 Jon 所提到的,最佳做法是使用限制写入量的函数(“n”变体),否则这些可能是缓冲区溢出漏洞利用的来源。

顺便说一句,“字符串”是一个非常糟糕的变量名称。

【讨论】:

    【解决方案2】:

    除此之外,您还允许最多 10 个字符的名字和最多 15 个字符的姓氏。如果达到(但未超过)这些限制并且年龄是一个两位数,则需要 66 个字符 - 因此您必须将 string 声明为一个 67 个字符的数组以应对(包括空终止符) .

    除此之外,您应该使用允许您限制输入大小的函数或格式字符串 - 目前,如果有人输入的名字超过 10 个字符(等),您将践踏其他内存。自从我编写任何 C 语言以来已经有一段时间了,但是使用“%10s”和“%15s”的格式字符串可能会在这方面有所帮助——或者使用fgets

    同样,我建议使用snprintf(或snprintf_s,如果您可以使用)而不是sprintf,以避免溢出输出问题。也可以使用所有这些方法的返回值来检测错误:)

    【讨论】:

    • 您可以使用scanf 来限制大小,但是达到所述限制时的优雅恢复是不必要的困难,因此推荐其他功能+1。
    【解决方案3】:

    您可以限制 scanf 读取的字符数量

    scanf("%9s", foo)
    

    最多读取 9 个字符,然后附加一个 NUL,适用于大小为 10 的缓冲区。

    【讨论】:

      【解决方案4】:

      我猜想这与string 数组的长度为 50 个字符这一事实有关,你在 sprintf 中拥有 37 个字符(如果我算对的话)加上 first 和另一个最多 11 个字符last 为 16,年龄可能为 2 或 3。加起来超过 50 个。一切正常,但您很可能会覆盖超过分配的 50 个字符的末尾。正如您所观察到的,这将“起作用”,但会破坏堆栈。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-12
        • 1970-01-01
        • 1970-01-01
        • 2021-03-28
        • 2012-11-08
        • 2019-09-04
        • 2020-07-26
        相关资源
        最近更新 更多