淺析一道有趣的陣列題
題目描述
對于一個共有10個整型元素的陣列,從首元素開始,從前往后回圈遍歷,修改元素的值,列印字串,
#include <stdio.h>
int main()
{
int i = 0;
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (i = 0; i <= 12; i++)
{
arr[i] = 0;
printf("hello world\n");
}
return 0;
}
運行結果
對于這個題目,咋一看給人的直覺就是執行13次回圈,列印13次hello world;當然也有可能是這樣一種結果:由于陣列越界訪問,所以將arr[9]的值改為0后,系統報錯,沒法運行,連除錯都過不去,
然而,令人震驚的是,在VS 2013編譯環境下,編譯器竟然沒有報錯,運行起來了!運行的結果出乎意料,竟是瘋狂列印hello world,死回圈!!!

結果分析與討論

下面由小濤給大家簡單分析一波:
-
在C語言中,記憶體主要可以劃分為:堆疊區,堆區,靜態區等部分,

-
對于區域變數和陣列,是在記憶體中的堆疊區開辟的,
-
堆疊區的使用特點是:先使用高地址空間,再使用低地址空間,
? 在這個案例中,由于先創建的是i變數,然后才是創建陣列arr,故i的地址要比arr陣列高,在VS 2013環境下,其記憶體開辟空間如下圖所示(注意i的地址):

-
對于陣列而言,其存盤和空間的關系是:隨著元素下標的增加,對應元素的地址也是由高到低變化的,
? 在此10個整型元素的陣列arr中,arr[0]的地址最低,arr[9]的地址最低,

為什么運行的結果會是死回圈呢?有必要對各數的地址進行探究一番,前面我們得到i的地址是0x010FFCD8,下面通過除錯,對其他資料的地址查看如下:

我們驚人的發現:arr[12]位置的地址也是0x010FFCD8,這意味著什么?這不是就是說arr[12]和i放在記憶體中的同一個地址嗎?如果把arr[12]的內容修改就會造成i的值被修改!結合我們得到的運行結果,這不是就能解釋了嘛,
當i =12時,執行arr[12] = 0指令后,i也被修改成0了;判斷條件i<=12恒成立,于是并沒有結束回圈,繼續i = 0,1,2,3,4,5,6,7,8,9,10,11,12,0,1,2·····于是乎持續輸出列印,
- 有一點需要注意,不同編譯環境下,i和arr的空間間隔不一定是差3位元組,親測發現gcc編譯器就不是這樣的分布,
哈哈,破案了~~

狄大人對這波分析很是贊同啊,元芳也表示很佩服!哈哈~~
漲姿勢咯,希望小伙伴們都有get到哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/300027.html
標籤:其他
上一篇:SSL證書錯誤怎么解決
