1.程序描述
#include <stdio.h>
int main()
{
int a =0;
short b = 0;
scanf("%d",&a);
scanf("%d",&b);
printf("a=%d\n",a);
printf("b=%d\n",b);
return 0;
}
2.程序执行
依次输入5和6,对变量a和b进行赋值,结果出现如下图所示的错误信息:
3.BUG分析
先说产生这个问题的原因:因为局部变量b的类型为short型,占据2个字节。在使用scanf()函数尝试为变量b输入值时,使用的控制格式为“%d”,然而,“%d"在定义上是表示有符号整型数据(int类型),共占用4个字节。这样就会导致在使用”%d”格式输入short型变量时,实际上会修改4个字节而非2个字节。另一方面,局部变量b在栈空间中本来只占用2个字节,但是经过scanf()函数输入后,将修改从变量b起始地址开始的4个字节,也就会将变量b附近的栈空间修改,所以系统最后会报出栈空间被破坏的错误。下面贴出具体的栈空间调试信息:
3.1.首先定位到变量b的地址,查看初始值
如下图所示,在初始条件下,变量b的地址为“0x008FFA5C”,对应的内存值为0x0000,后续几个字节空间的值为0xCC。
3.2.输入值后,再看变量b附件的栈空间
如下图所示,在输入6后,变量b附近的栈空间变为了0x06 0x00 0x00 0x00,这样就对原始的后续两个字节栈空间进行了非法修改,所以系统会报错。
4.正确做法
正确的做法应该是在通过scanf()函数输入变量b的时候,使用”%hd",表示使用短整型格式输入,这样就只会修改变量b所属的两个字节
#include <stdio.h>
int main()
{
int a =0;
short b = 0;
scanf("%d",&a);
scanf("%hd",&b);
printf("a=%d\n",a);
printf("b=%hd\n",b);
return 0;
}
结果如下,将不会报出错误信息。