首页 > 代码库 > 字符串比较,栈溢出引起的程序bug

字符串比较,栈溢出引起的程序bug

需求

  输入密码字符串,与设定的密码“1234567”进行比较,两者相符则输出"congratulations!”,不符则输出“try again!”。

程序bug

  实际运行过程中发现,输入某些8位字符串,如33333333,也会得到"congratulations!”,这与预期功能不符。

出现bug的原因

  在程序编写过程中,出现冗余语句(见代码注释),输入的str长度大于buf,导致栈溢出。ret定义在buf之前,往内存里存储数据时,ret被踩,首字节被占用。

  当输入的字符串str与PASSWORD比较,str > PASSWORD时,ret的值为1,内存显示为 10 00 00 00,被踩后首字节变成00,内存显示为 00 00 00 00,则ret的值为0,输出"congratulations!”;

  当输入的字符串str与PASSWORD比较,str < PASSWORD时,ret的值为-1,内存显示为 FF FF FF FF,被踩后首字节变成00,内存显示为 00 FF FF FF,则ret的值不等于0,输出“try again!”。

什么是栈溢出?

  栈溢出就是缓冲区溢出的一种。 由于缓冲区溢出而使得有用的存储单元被改写,往往会引发不可预料的后果。程序在运行过程中,为了临时存取数据的需要,一般都要分配一些内存空间,通常称这些空间为缓冲区。如果向缓冲区中写入超过其本身长度的数据,以致于缓冲区无法容纳,就会造成缓冲区以外的存储单元被改写,这种现象就称为缓冲区溢出。

解决办法

  去掉代码中的冗余语句,同时交换ret与buf的定义顺序,避免ret被踩。

 

----------------------------华丽丽的分割线--------------------------代码君要出场了--------------------

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 #define PASSWORD "1234567"
 5 
 6 void cmp(char* str);
 7 
 8 int main()
 9 {
10     char buf[1024];
11 
12     printf("please input password:\n");
13     scanf("%s", buf);
14     cmp(buf);
15 
16     return 0;
17 } 
18 
19 void cmp(char* str)
20 {
21     int ret;                                 //ret定义在buf之前,往内存里存储数据时,ret被踩
22     char buf[8];
23 
24     ret = strcmp(str, PASSWORD);
25     strcpy(buf, str);                       //冗余语句,输入的str长度大于buf,导致栈溢出
26     
27     if(ret == 0)
28         printf("congratulations!\n");
29     else
30         printf("try again!\n");
31 }