错误:围绕堆栈变量“串”被损坏

问题描述:

我有一个小问题,下面的代码。这是一个简单的程序,它读取两个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 - 围绕堆栈变量“字符串”已损坏。 这有点令人困惑,我找不出问题出在哪里。我会感谢 任何建议。

+1

不相关,但如果您有C99(或保证其某些部分),则应该使用`snprintf`来代替以防止发生这种问题。 – 2011-01-10 07:21:44

你写更多的字符转换成比它的房间分配给“串”(即大于50)

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

正如乔恩所说,它是使用限制多少,他们写的(“N”个变种)功能的最佳实践,否则这些都可以bufferoverrun攻击的来源。

顺便说一句“字符串”是一个可变的一个非常可怜的名字。

我猜这是什么做的事实string数组的长度为50个字符,你在sprintf的37(如果我算右),加上随后长达11 first另有16 last ,加上年龄可能为2或3。总计超过50个。一切正常,但你很可能覆盖超过50个字符分配的结尾。正如你所观察到的那样,这将“起作用”,但会腐蚀堆栈。

从别的

除此之外,你允许的最多10个字符的名字和最多15个字符的姓氏。如果这些限制达到(但不超过)和年龄是一个两位数,这将需要66个字符 - 这样你就必须声明string是67个字符数组来应付(包括空终止符)。

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

同样,我会建议使用snprintf(或snprintf_s如果它提供给你),而不是sprintf避免超速输出问题。使用所有这些方法的返回值来检测错误,太:)

+0

您可以使用`scanf`限制尺寸,但在达到上述限制时恢复到正常状态会造成不必要的困难,因此建议使用+1来实现其他功能。 – 2011-01-10 07:20:29

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

scanf("%9s", foo) 

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