2013-04-26 60 views
2

下面的字符串是代碼供應未空終止STRCPY

smem_dmp(char *name, char content[]) 
{      
     int i; 
     int len = strlen(content);  

     printf("%s\n\n", name); 

     for(i = 0; i < len; i++) 
     { 
      printf("%c\t%p\n", content[i], &content[i]);  
     } 

     printf("Done\n\n"); 
} 

print_bar() 
{ 
    printf("********************************************************************\n"); 
} 

int main(int argc, char *argv[]) 
{ 
    char a[16]; 
    char b[16]; 


    strcpy(a, "abcdefghijklmnop"); 
    printf("a = %s\nb = %s\n\n",a,b); 

    smem_dmp("A", a); 
    smem_dmp("B", b); 

    print_bar(); 

    strcpy(b, "ABCDEFGHILKLMNOP"); 
    printf("a = %s\nb = %s\n\n",a,b); 

    smem_dmp("A", a); 
    smem_dmp("B", b); 

    system("PAUSE");  
    return 0; 
} 

通過觀察A和B駐留在內存中我曾發生了什麼事。複製到b的字符串不是空終止的。這導致a的內容被刪除,因爲b在內存(0028FF30)之前位於(0028FF20)。

發生了什麼事? strcpy(b,「string」)在經過堆棧幀變量的所有內存之後才停止嗎?對不起,如果我不使用正確的術語。 :)

+1

你的數組'a'太小了。它至少需要17個元素。 – 2013-04-26 13:58:47

+0

謝謝。我知道。這比理解代碼更重要的是理解安全性。 – user84628 2013-04-26 14:01:10

+1

是的,它會繼續複製字節,直到它在任何正在訪問的隨機存儲器中達到零字節,或者它到達不可訪問的存儲器並導致存儲器故障。如果佈局如您所說,那麼如果在它崩潰之前它到達那裏,那麼它最終會在其他字符串中亂寫。這些都不是由任何標準定義的,它只是常用的實現。 – jcoder 2013-04-26 14:06:40

回答

6

這是怎麼回事? strcpy(b,"string")不會停止,直到它已經通過堆棧幀變量的所有內存?

strcpy複製字節直到它在源中找到一個0字節。將其複製到目標,然後返回strcpy。 (如果目標不是大到足以容納源包括0 - 終止,該行爲是不確定的,但除非你得到一個分段錯誤,那是你可以依靠在發生什麼樣的做法。)

所以

strcpy(b, "ABCDEFGHILKLMNOP"); 

副本17個字節 - 的16個字母和0終止子 - 從字符串文字到陣列b,其中僅包含16個元素。這意味着0終結符被寫入數組b末尾的一個元素。在你的情況下,這是a中的第一個字節,而strcpy(b, "ABCDEFGHIJKLMNOP");實際上使得a包含一個空字符串。

2

"abcdefghijklmnop"尺寸爲16和你a數組的大小爲16應該是17(16 + 1空終止charachter)