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