/----------------------------------------------------------------------/
六。越界檢查
由于在DOS下,DOS系統(tǒng)根本不會去檢查程序的訪問越界問題,無論你要對內(nèi)存的哪里
進行讀寫,都是允許的(只要不把自己程序的代碼區(qū)改寫了就沒事)。但在Windows下,
尤其是WinXP,內(nèi)存是分塊的,對只讀塊寫數(shù)據(jù)或者對不可讀寫塊進行讀數(shù)據(jù)都會引發(fā)
異常,如果程序不能夠處理這個異常,那么這個程序就會被強制關(guān)閉。有了這個異常
機制,當(dāng)然會使你更容易查出程序的錯誤。特別地,在VC6的Debug模式下,
堆里未被初始化的內(nèi)存被0xCD字節(jié)模式填充,堆里釋放的內(nèi)存被0xDD字節(jié)模式填充。
于是一但發(fā)生越界的時候,很容易通過程序運行結(jié)果得知當(dāng)中有錯,為調(diào)試帶來了方便。
然而TC則不然,不管你越界了多少,你都收不到任何的警告或者錯誤。
而且在多數(shù)情況下,TC下運行正常的越界代碼換VC6上就會結(jié)果出錯。
有初學(xué)者以為這是VC6編譯器有問題,其實不然,而是TC給你掩蓋了這個錯誤。
#include <stdio.h>
int main(void)
{
int n;
int num[8];
int sum[8] = {0};
for(n=1;n<=8;++n)num[n] = 1;
for(n=1;n<8;++n)sum[n] = num[n]+num[n+1];
for(n=1;n<8;++n)
printf("%d\n", sum[n]);
getchar();
return 0;
}
這個程序的目的是給num數(shù)組全部給1,然后sum數(shù)組計算num相鄰兩個數(shù)的和。
有的初學(xué)者可能會說,這個程序沒問題,如果他以為int num[8];的下標(biāo)是從1至8的話。
然后,照樣運行一下看看。TC的結(jié)果是7個2,結(jié)果正常。
VC6的結(jié)果是,什么都沒有顯示,然后你打開資源管理器查看一下進程,
你就會發(fā)現(xiàn)這個程序占用CPU高達(dá)90%以上。你不要以為這是編譯器發(fā)生了問題,
原因正是因為這里的越界導(dǎo)致了一個死循環(huán)!如果是GCC或更高版本的VC編譯器,
把for里的8改成11也會發(fā)生死循環(huán)。但即使改成11,在TC上運行的結(jié)果也非常正常,
TC里完全沒有任何錯誤的征兆。這里不分析這個死循環(huán)產(chǎn)生的原因,這里只是想告訴你,
你在TC上運行結(jié)果無誤的程序不一定就邏輯上正確了(包括VC和GCC)。特別是TC幾乎
沒有任何的越界檢查,所以更要求程序員在TC上編寫代碼時候要十分謹(jǐn)慎和細(xì)心。
但現(xiàn)在問題是現(xiàn)在使用TC的大多是初學(xué)者,在沒有什么經(jīng)驗的情況下,很大可能
會寫出類似這樣的越界訪問代碼。這種代碼也許在TC上沒有問題,可是只要換一個
編譯環(huán)境,問題就馬上暴露出來了。不信就看看下面的經(jīng)典TC錯誤代碼吧:
#include <stdio.h>
int main(void)
{
char *pstr;
gets(pstr);
puts(pstr);
getchar();
return 0;
}
(別告訴我說你不知道這代碼錯在哪里,你不知道錯哪里的話那你平時一定是使用TC的)