2013-07-14 55 views
3

我正在關注「粉碎堆棧以獲得樂趣和利潤」http://insecure.org/stf/smashstack.html粉碎堆棧:爲什麼此代碼有效?

我想知道爲什麼我的代碼正在工作,雖然我寫了它來做出分段錯誤。

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

void function(char *str){ 
    char buffer[16]; 
    strcpy(buffer, str); 
} 

int main(void) 
{ 
    char large_string[256]; 
    int i; 

    for(i = 0; i < 255; i++) 
     large_string[i]; 

    function(large_string); 
    return 0; 
} 
+0

for循環體中沒有東西丟失嗎?我認爲這是一種不完整的陳述。 – junix

+3

bcoz即使在未定義行爲的情況下,分段錯誤也不確定:) – VoidPointer

+0

@junix不完整,但沒有超出範圍 –

回答

6

這只是因爲你的large_string沒有正確的初始化:它含有垃圾,其長度(數字節直到'\0')最可能遠小於256(例如,在我的機器上,large_string的第四個字節爲零,因此strcpy只複製4個字節)。

讓它

for(i = 0; i < 254; i++) 
    large_string[i] = 'A'; 
large_string[255] = '\0'; 

,你會得到分段錯誤。

0

要初始化在large_string[256];的字符串,然後通過它的項目。你不通過數組的限制,所以沒有分段錯誤。

如果你把值在數組中,然後程序會崩潰,因爲strcpy的意志得到了超出範圍

+1

只要large_string的前16個元素之一是'\ 0',它就會保持爲真。否則,strcpy應該打破函數中聲明的緩衝區的限制。 – junix

+1

'large_string'未初始化幷包含垃圾。 'strcpy'複製數據直到第一個'\ 0'。這真是幸運。 – Inspired

+0

的確如此,我會在 –

0

您尚未正確初始化large_string

在for循環之後,在數組\0的末尾添加空字符可能有所幫助。

large_string[255] = '\0'; 

最好是初始化數組,而不是現在它將垃圾值。

for(i = 0; i < 255; i++) 
    large_string[i] = 'a'; 

編輯:

正如註釋,junix所述 - 更重要的是,沒有\0至少16個字節比具有\ 0在字節255挑起堆粉碎;-)

+1

的評論中加上這一點,我認爲至少有16字節沒有'\ 0'比在字節255有一個'\ 0'來激發堆棧粉碎更重要 - ) – junix

+0

沒錯 - 與你同意。 –

1

也許,執行發生large_string初始化爲全零。而strcpy實際上覆制了一個空字符串。

for(i = 0; i < 255; i++) 
    large_string[i] = 'a'; 

這將導致分段錯誤。