2011-02-01 64 views
2

我對這個關於for循環的神祕卡住了。關於for循環的神祕

int abc[3], i, j; 
    for(j=0; j<3; j++); 
    printf("%d\n", j); 
    abc[j] = abc[j] + 3; 
    printf("%d \n", j); 


Output: 

3 
6 

輸出應該是3,3因爲我沒有改變j的值。

將3添加到abc的第j個值導致j的值發生3的變化。這隻會在從for循環退出然後嘗試更改abc [j]的值時發生。

也許我錯過了一些非常明顯的東西。任何幫助將非常感激。

+0

我得到3 3作爲我的VC++編譯器的輸出 – 2011-02-01 07:08:05

+0

什麼是數組abc初始化爲? – 2011-02-01 07:11:13

回答

15

你有一個緩衝區溢出,因爲你聲明你的數組的大小爲3 int abc[3];但你索引的第4個元素;這是未定義的行爲

abc[j] = abc[j] + 3; // j = 3 here, overflow 

你最有可能看到的是,j位於堆棧上剛剛過去的陣列abc,所以當你溢出一個過去的數組abc[3],你實際上修改包含j內存。

*請注意,在C標準中沒有任何地方提到堆棧,這是一個實現細節,可以從系統更改爲系統。這部分是它的原因,因爲它是未定義的行爲,並且您從他們看到兩個3作爲輸出的人得到迴應。

5

您正在索引數組末尾(緩衝區溢出)並重新分配堆棧上的其他變量。

int abc[3], i, j; 
// Your stack looks like this (single 'x' is one byte): 
// |abc[0]|abc[1]| abc[2]| j | i | 
// 
// |xxxx |xxxx |xxxx |xxxx|xxxx| 
// 
for(j=0; j<3; j++); 
printf("%d\n", j); 
// j = 3 at this point 
// abc[3] points past the end of the array abc, in this case, at j. 
// So the next statement increments j by 3. 
abc[j] = abc[j] + 3; 
printf("%d \n", j); 

要驗證,嘗試在末尾添加以下語句:

printf("%d\n", &i == &abc[3]); 
printf("%d\n", &j == &abc[3]); 

編輯

堆棧將取決於你使用的編譯器物質的確切佈局:

[email protected]:~/Desktop/stackoverflow$ gcc --version 
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3 
Copyright (C) 2009 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
[email protected]:~/Desktop/stackoverflow$ ./a.out 
3 
3 

這就是爲什麼它的工作原理Ë我的機器上 - 聲明:

printf("abc: %x abc[3]: %x i: %x j: %x\n", &abc, &abc[3], &i, &j); 

給出了下面的輸出:

abc: 4cd0aa70 abc[3]: 4cd0aa7c i: 4cd0aa8c j: 4cd0aa88 

所以堆棧居然是:

// aa70 aa74  aa78 aa7c   aa88 aa8c 
// |abc[0]|abc[1]| abc[2]|  | .... | j | i | 

所以當它訪問abc[3],它的訪問0x4cd0aa7c這只是「死亡空間」。

+0

我認爲它應該在那裏... – ClosureCowboy 2011-02-01 07:03:47

+0

對不起,這是我第一次急速編輯。我在更新時刪除了它,但顯然我不夠快。 – misha 2011-02-01 07:11:57

1

當J = 3時,abc [j]指向第4個元素,因爲數組索引以0開頭而不是1開頭。因此,您試圖訪問超出數組abc內存區域的位置。巧合的是,這個位置恰好是J.因此,J的價值得到了修改。嘗試更改變量聲明的順序以更好地理解此行爲。

謝謝,
Vamyip

0

對於(j = 0;Ĵ< 3; J ++);

您在for循環結尾處有分號。問題解決了。