轉自 http://westsoftware.blog.163.com/blog/static/2609410920091953456841/
最近一直在看Andrew Koening寫的書籍,可以說學習C/C++或者從事這方面的開發的人員非常值得一看的書籍,這裡我推薦看看《C陷阱與缺陷》與《C/C++沉思錄》。
這裡先來看看《C陷阱與缺陷》一段代碼。
#include <stdio.h>
int main()
{
int i;
char c;
//printf("i address:%ld/n",&i);
//printf("c address:%ld/n",&c);
for(i=0 ; i<5; i++)
{
scanf("%d",&c);
printf("%d ",i);
}
return 0;
}
==========
這麼精小的一段代碼,看看運行結果將會是什嗎?請看清楚C是字元變數。
剛開始的時候,對他講的東西不是很明白,為了更加清楚,分析相關記憶體結構。
由於scanf指向的是一個整形指標,此時C接收字元錄入,所以在給C輸入資料的資料的時候,會將i的一些記憶體位址進行覆蓋,怎麼覆蓋的呢?在 FC6下,會將i的低端地址覆蓋成C的高端地址,不知道這麼說能不能明白?就是說C實際接收了一個整形變數,但是C存不下,多出的那部分怎麼辦呢?就將C 的高端地址位覆蓋成I的低端地址位了,所以I的值一直都是0,所以在運行此程式是一個死迴圈狀態。
上面注釋掉那兩段,可以列印看看C與I的地址。我這裡列印的地址是連續的。
但是在VC6中,是可以正常啟動並執行,這就是我說的記憶體位址覆蓋方式不一樣,換句話說,怎麼覆蓋是有編譯器決定,這裡我是這麼猜想,VC覆蓋記憶體的時 候是C的左徹的那段記憶體而不覆蓋I的記憶體位址,所以在VC中能正常。
這也是一個猜想,怠於證實。而在FC中是“往右”進行覆蓋。
所以開發的時候,一定要注意,這種陷阱一旦走進去的,就很難調試,有時候也有一種“湊巧”來避開這個問題,差錯就更加不好查。希望在以後開發的時候 能給大家有一定的參考。