這兩天被人問了一個問題說假如C/C++訪問下表越界的數組元素會報錯么,於是充滿好奇心的我動手試了一下,WTF,果然沒有報錯,但是會給程序帶來莫名其妙的結果(比如十次的循環但是變成了死循環,但八次卻可以)
例:
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 //int A[5]={0}; 5 int main() 6 { 7 int A[5]={0}; 8 //int *A=(int*)calloc(5,sizeof(int)); 9 for(int i=0;i<8;++i) 10 { 11 //A[i]=1; 12 printf("%d\n",A[i]); 13 } 14 15 return 0; 16 }
程序結果:
C語言的編譯器是不檢查下標越界的,以前知道這個問題,可是沒有想過是什么原因?
總結如下:
1,不檢查下標是否越界可以有效提高程序運行的效率,因為如果你檢查,那么編譯器必須在生成的目標代碼中加入額外的代碼用於程序運行時檢測下標是否越界,這就會導致程序的運行速度下降,所以為了程序的運行效率,C/C++才不檢查下標是否越界。
2,不檢查下標是為了給程序員更大的空間,也為指針操作帶來更多的方便。如果有這個檢查的話指針的功能將會大大被削弱,C的數組標識符,里面並沒有包含該數組長度的信息,只包含地址信息,所以語言本身無法檢查,只能通過編譯器檢查,而早期的C語言編譯器也不對數組越界進行檢查,只能由程序員自己檢查確保。以及在早期的CRT函數中也不對字符串指針或數組進行越界檢查,都是要求程序員確保空間足夠,因此也才也才有了在VS2005之后微軟提供的安全的CRT函數版本。
自己寫了一段檢測程序測試這個問題,發現如果數組下標越界了,那么它會自動接着那塊內存往后寫。想了一下明白了,以前說不允許數組下標越界,並不是因為界外沒有存儲空間,而是因為界外的內容是未知的。也就是說如果界外的空間暫時沒有被利用,那么我們可以占用那塊內存,但是如果之前界外的內存已經存放了東西,那么我們越界過去就會覆蓋那塊內存,導致錯誤的產生。。。
這樣就明白了,所以我們還是需要好好規划數組的下標滴。
C語言好像沒有直接取得數組長度的函數,只有取得數組所占內存大小,再除以一個元素占用的內存大小來計算數組長度。
1 int a[8]; 2 printf("%d",sizeof(a)/sizeof(a[0]));