2014-02-26 26 views
3
char r[40]; 
strcpy(r,"abcdef"); 
strcat(r,r); 

我的程序在第三行崩潰?如果使用相同的陣列作爲兩個參數,strcat()崩潰

更換strcat的(R,R);通過strcat(r,「abcdef」);工作正常,但....爲什麼呢?

+0

想想如何自己實現'strcat()'這可能是一個很好的學習經驗(這是一個非常簡單的函數)。然後檢查您的實現是否處理自串聯,以及您可能需要做些什麼才能使其能夠處理它。然後考慮是否每個調用'strcpy()'的人都應該支付一些功能,比如自連接(self-concatenation),這些功能可能很少使用。 –

回答

0

strcat()從輸入讀取並將其複製到輸出,直到它在輸入中找到一個\0終止符。通過爲輸入和輸出指定相同的數組,您正在修改正在讀取的輸入。

你必須檢查你的編譯器的具體實現的strcat(),但如果你跟蹤通過一個簡單的執行類似以下,你應該爲什麼你的代碼崩潰後的一段時間看:

char *strcat(char *dest, const char *src) 
{ 
    char *ret = dest; 
    if (dest && src) 
    { 
     while (*dest != 0) 
      ++dest; 
     while (*str != 0) 
      *dest++ = *src++; 
     *dest = 0; 
    } 
    return ret; 
} 

while (*dest != 0)循環後, dest現在指向輸入的終止符\0。在while (*str != 0)循環的第一次迭代,然後替換終止與a,從而導致循環到它應該不再停止。最終,循環將超過輸入的範圍,並開始閱讀周圍的內存,並最終如果沒有找到擊球無效的內存之前另一\0字節就會死機。

3

根據strcat(3)

strcat()功能追加SRC字符串到DEST串,覆蓋在dest的端終止空字節(「\ 0」),然後將一個空結尾字節。 該字符串可能不重疊,且dest字符串必須有結果了足夠的空間。

2

原因是strcat在本例中的第一件事是覆蓋char * r的終止空值。然後它會遍歷r,尋找它被覆蓋的空值,最終轉移到不安全的內存中(具體取決於堆棧的方向)

解決方案類似於strncat(r,r,strlen(r))它將在空值被覆蓋之前捕獲R的長度。

2

遲到的回答。只是想添加一些「圖形」的解釋。

如果您考慮如何實現strcat,它會在源字符串的第一個字符處初始化一個指針,並逐個遍歷源字符,直到達到其空字節。但是由於源字符串和目標字符串相同,因此可能會發生以下情況。

存儲器開始了這樣的:

a b c d e f \0 

源極(S)和dest(d)指針都指向a上函數入口。該DEST指針移動到結束,我們準備複製

s   d 
a b c d e f \0 

    s   d 
a b c d e f a 

    s   d 
a b c d e f a b 

     s   d 
a b c d e f a b c 

     s   d 
a b c d e f a b c d 

      s   d 
a b c d e f a b c d e 

      s   d 
a b c d e f a b c d e f 

       s   d 
a b c d e f a b c d e f a 

你可以看到,源指針不會達到其終止null字節,因爲這讓一開始疲憊不堪。最終我們會在這裏耗盡空間。

因此,由於這是一種可能的情況,所以strcat的定義不允許兩個字符串重疊。這種方式可以自由使用基本的實現。

相關問題