程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 字符串比較,棧溢出引起的程序bug

字符串比較,棧溢出引起的程序bug

編輯:關於C語言

需求

  輸入密碼字符串,與設定的密碼“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 }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved