C语言数组越界导致无限循环
大獎也是你們的,感謝支持,不喜歡的請輕拍。過年抽獎我還是很期待的,每年公司的年會抽獎的時候,我總是能小中一把,有一年我還中了個一等獎,不知道大家對一等獎什么概念,中一等獎的概率非常低,集人品運氣于一身的,我當時醞釀了全宇宙的力量,不說了,發功的時候真的非常累。
就是這個截圖,我看了下,感覺有點意思,趕緊就自己敲下代碼看看是怎么回事,可惜的是,我怎么也沒看到出現無限循環啊。
代碼如下:
#include "stdio.h"int main() {int a[10] , i;for(i = 1;i<= 10;i++){a[i] = 0;printf("%d %d\n",i,a[i]);} return 0; }我先是在 dev c++ 上面試了下,結果如下
我這時候想,黃兄是不是忽悠我了,我要去成都叫他請我吃飯,然后我就給他評論
評論如下
竟然還有人給我的評論點贊了,啊啊啊啊啊啊~
不死心,趕緊又到Linux 下用 gcc編譯 結果如下
還是沒有無線循環,我要死了,要是在群里面討論這個,我要是說不出來會不會丟臉一個晚上。
趕緊用大招,看看i的地址和a[i] 的地址
看這個圖,i等于 10的時候, &a[10] 的地址和 i的地址還是獨立的,雖然 a[10]已經超過了 數組的范圍,但是并沒有對i造成任何影響。
然后,我腦子一響,突然頓悟發現這個代碼的問題所在了,這個數組越界沒有越過去,要是越過去了,侵犯了i的領土「內存地址」了肯定就死循環了。
代碼修改一下
#include "stdio.h"int main() {int a[10] , i;for(i = 1;i<= 12;i++){a[i] = 0;printf("%d %d\n",i,a[i]);} return 0; } 你看,你看,這樣一越界過去,就產生了死循環,i一直都是0,怎么也跳不出for循環了。看看內存分布上圖中 i = 10的時候,&a[10]?還沒有越界到?&i「i的地址」,等下一次循環 i = 11的時候,那 &a[11]? 就等于?&i 了,a[11] = 0,其實也就是 i=?0,死循環也就是這樣來了。
從這個例子我們可以明白一點,為什么數組不能越界操作了沒?如果真的是項目里面的代碼,要是編譯器也不給出提示,那么你即將構造一個非常難排查的bug出來。
如果對上面的地址還是不感冒,可以看看這個圖片
a我們定義的是10的大小,但是我們使用 a[10],這個是越界操作,越界操作編譯器不會提示編譯出錯,但是這樣操作就可能侵犯到i的地址,實際上把i給賦值了,所以會導致i=0,一直跳不出for循環。
我們正常一個數組遍歷會這樣寫
#include "stdio.h"int main() {int i;int a[10];for(i = 0;i < sizeof(a)/sizeof(a[0]);i++){a[i] = 0;printf("%d %d %p %p\n",i,a[i],&i,&a[i]);} return 0; }編譯器就好像法律,約束著人們的行為,但是有些法律沒有涉及到的,就很容易被打擦邊球。
最后用這個代碼看看內存的增長「一個讀者奉獻的」
#include <stdio.h>int main(void) {#pragma pack (4)int j;int a[10];int i;#pragma pack()printf("a=%p &a[10]=%p &i=%p &a[-1]=%p &a[-2]=%p &j=%p\r\n",a, &a[10],&i,&a[-1],&a[-2],&j);return 0; }總結
以上是生活随笔為你收集整理的C语言数组越界导致无限循环的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Unity内置管线Projector原理
- 下一篇: sql插入多条记录_如何在SQL中插入多