我用的示例工作關於SEG故障:不可預測的行爲
char m[10]="dog";
strcpy(m+1,m);
以我CENTOS機的結果如預期:段故障。但在Ubuntu上並沒有發生。然後我添加一個printf(「%s」,m);到Ubuntu上的代碼,令人驚訝的是我得到了「ddog」。 我使用GCC和ubuntu版本是最新的。 誰能告訴我爲什麼結果是不同的。我也檢查了raspbian,我也收到了分段錯誤。
感謝,
我用的示例工作關於SEG故障:不可預測的行爲
char m[10]="dog";
strcpy(m+1,m);
以我CENTOS機的結果如預期:段故障。但在Ubuntu上並沒有發生。然後我添加一個printf(「%s」,m);到Ubuntu上的代碼,令人驚訝的是我得到了「ddog」。 我使用GCC和ubuntu版本是最新的。 誰能告訴我爲什麼結果是不同的。我也檢查了raspbian,我也收到了分段錯誤。
感謝,
爲m
的內存是:
+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+
WHE你初始化:
char m[10] = "dog";
前四個要素m
被初始化。其餘的都已初始化。
+---+---+---+----+---+---+---+---+---+---+
| d | o | g | \0 | ? | ? | ? | ? | ? | ? |
+---+---+---+----+---+---+---+---+---+---+
我正在使用?
來指示未初始化的內存位置。他們可以包含任何東西,包括 。通過
strcpy(m+1, m);
一步一步執行
讓我們走。
步驟1:將m[0]
複製到m[1]
。所以,你必須:
+---+---+---+----+---+---+---+---+---+---+
| d | d | g | \0 | ? | ? | ? | ? | ? | ? |
+---+---+---+----+---+---+---+---+---+---+
步驟2:m[1]
被複制到m[2]
。所以,你必須:
+---+---+---+----+---+---+---+---+---+---+
| d | d | d | \0 | ? | ? | ? | ? | ? | ? |
+---+---+---+----+---+---+---+---+---+---+
第3步:m[2]
被複制到m[3]
。所以,你必須:
+---+---+---+---+---+---+---+---+---+---+
| d | d | d | d | ? | ? | ? | ? | ? | ? |
+---+---+---+---+---+---+---+---+---+---+
strcpy
終止,當它遇到源 參數空字符。正如你所看到的,strcpy
的終止標準決不會符合 。因此,程序繼續讀取超出有效限制的內存中的數據,並將數據寫入內存超出有效限制。
這是導致未定義的行爲。
要獲得期望的結果,"ddog"
,你可以使用:
size_t len = strlen(m);
for (int i = len; i >= 0; --i)
{
m[i+i] = m[i];
}
「預期」 ←有您的問題。 「未定義的行爲」就是這個意思。 – jthill
謝謝,我的期望是完全錯誤的 – Mahdi