2016-04-26 53 views
0

我寫了一些代碼在C應該strcpy一些輸入數據到聲明的緩衝區。下面的代碼:C複製到兩個緩衝區,但只有一個應該填充

#include <stdio.h> 
#include <string.h> 

void function(char *args) { 
    char buff_1[12]; 
    char buff_2[3] = "ABC"; 

    strcpy(buff_1, args); 
    printf("buff_1: %s \n", buff_1); 
    printf("buff_2: %s \n", buff_2); 
} 

int main(int argc, char *argv[]) { 
    printf("Input: "); 

    if(argc > 1) 
    function(argv[1]); 

    return 0; 
} 

如果我現在運行的二進制我會承擔一切超過11個的輸入參數會導致緩衝區溢出,但實際上它追加我輸入兩個緩衝器:

./main (perl -e 'print "A"x15') 
buff_1: AAAAAAAAAAAAAAA 
buff_2 :ABCAAAAAAAAAAAAAAA 

而且檢查使用gdb的變量顯示,我的輸入參數存儲在兩個緩衝區:

(gdb) x/1s buff_1 
0xffffd284: 'A' <repeats 11 times> 
(gdb) x/1s buff_2 
0xffffd281: "ABC", 'A' <repeats 11 times> 

我編寫的代碼中使用以下命令:gcc -m32 -O0 -g -fno-stack-protector -o main main.c使用gcc (Ubuntu 5.2.1-22ubuntu2)

有人可以解釋這可能嗎?

+0

你究竟認爲緩衝區溢出的結果應該是什麼? –

+0

如果你打印出變量的地址(帶有'%p'),你會發現它們奇蹟般地相互對齊,所以「ABC」(末尾沒有零)將會跟隨buff_2內容。 – Koshinae

+1

或者根本不計算,'char buff_2 [] =「ABC」;'。並啓用編譯器警告。 – Lundin

回答

4

對於buff_2,您沒有足夠的空間終止空終止。所以printf("buff_2: %s \n", buff_2);會溢出你的緩衝區,導致未定義的行爲

char buff_2[3] = "ABC"; // Not enough space for \0 
char buff_2[4] = "ABC"; // OK 
char buff_2[] = "ABC"; // OK, Size will be 4 
+0

我的編譯器在這一行上拋出一個錯誤:'char buff_2 [3] =「ABC」;':_'ABC':array bounds overflow_ –

3

寫入更多的字符到緩衝區比有空間調用未定義的行爲。沒有可預見的結果;當你這樣做時你無法承擔任何事情。你不能指望總是得到確定性的運行時錯誤。

這就是爲什麼您需要在將參數傳遞到strcpy之前檢查參數的大小。不這樣做是一個錯誤。

作爲一個附註,你在這裏有一個bug:char buff_2[3] = "ABC";。沒有足夠的空間進行空終止。這意味着當您嘗試打印該數組時,會調用未定義的行爲,因爲它不是有效的,以空字符結尾的C字符串。

相關問題