輸入密碼字符串,與設定的密碼“1234567”進行比較,兩者相符則輸出"congratulations!”,不符則輸出“try again!”。
實際運行過程中發現,輸入某些8位字符串,如33333333,也會得到"congratulations!”,這與預期功能不符。
在程序編寫過程中,出現冗余語句(見代碼注釋),輸入的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 }