標籤:null 指標 應該 之一 name 應對 schema Owner deb this
Access Violations<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
存取違規
A. 簡介
B. 設計期間的AVs
a. 硬體原因
b. 軟體原因
c. 庫的錯誤
d. 升級C++Builder
C. 運行期間的AVs
a. 程式退出時發生AVs
b. 將你的指標設為空白指標!
c. 使用IDE管理!
d. 在Form中使用caFree!
e. 隨機AVs(非退出)
D. 使用者提出的更多建議
簡介
存取違規(AVs)是Windows編程時發生的最麻煩的錯誤之一。儘管很難用一篇文章來解釋清楚所有可能導致AVs的原因,我將儘可能的解釋所有我所知道的原因。若您有本文中未提及的AVs的解決辦法,請Email給作者。您的經驗將加到本文中。
C++Builder中發生的AVs主要有兩種形式。設計期間的AVs和運行期間的AVs。我們開始討論吧。
設計期間的AVs
設計期間的AVs最容易捕捉到,但靠您自己很難真正除掉它。它們通常產生於編譯時間、Builder啟動和關閉時,或者幾乎是隨機的。讓我們先討論以下這些已知的原因。
硬體原因
某些顯卡、雙處理器主板、和聲音裝置會導致C++Buider中的AVs。為什嗎?您機器中的每一塊板卡都帶有裝置驅動。由於製造商、Windows版本、你使用的C++Builder版本的不同而存在相容問題,會導致AVs問題。解決這種情況的步驟如下:
o 總是使用您系統組件的最新驅動程式。若您使用隨Windows所帶的驅動程式的話,你應從製造商那兒擷取最新的升級版本。
o 訪問Borland.Com和DejaNews.Com上的新聞群組,尋找關於您的硬體裝置的主題。某些顯卡已知有相容問題。您可能需要更換硬體。使用人所共知的穩定且成熟的廠商提供的硬體是個好主意。Matrox就是個顯卡的好例子。
o 檢查您所安裝的裝置之間有沒有衝突是個必須的步驟。
o 對一些古怪的顯卡驅動程式來說,有時調低解析度有助於穩定。
o 若您使用雙處理器的話,確保兩個處理器的step revision相同,就是要用完全一樣的兩個晶片啦。
軟體原因
儘管Windows是Intel體系中使用最廣泛的作業系統,但它的曆史是充滿BUG、不穩定的。有許多方法能幫您擁有一個更穩定的編程工作站。按以下步驟將幫你預防此類AVs的發生。
o 禁用裝有Internet Explorer (IE) 4.x或更高版本的Windows工作站上的Active Desktop。儘管這個功能可以讓您定製自己的案頭,但同時也導致許多應用程式產生問題。
o 儘管Windows 9X更福士化,NT4(NT5)提供了幾乎是所有Windows平台中最穩定的環境。我想強調這應是C++Builder程式員選擇的環境。
o 確保安裝了最新的NT系統補丁(SPx),每次發布的補丁都讓您的NT系統變得更穩定。
o 在升級了主要軟體包後,重新安裝最新的SPx。包括MS Office,IE,甚至是在C++Builder安裝後,某些SPx更新的檔案經常在安裝驅動時被覆蓋。如果SPx提問是否用舊版本取代新版本時,回答否。
o 我們的經驗是當你發現新裝的系統,經過一段時間後開始出現越來越多的問題時(包括AVs),重裝系統可以解決絕大多數的問題,並可以提高系統的整體效能。這可能很費時,但絕對有效。
庫的錯誤
安裝了新的庫和組件後,應該跟蹤一下並看一看是否有對設計期間AVs的更正。若發生了新的AVs,你也許希望卸載最近安裝的組件。如果AVs也消失的話,尋求供應商的支援。
同時應對ReadME檔案與安裝簡介多加註意。如果你升級了一個庫,這也許需要你改變你的include目錄設定,甚至修改你的make檔案,來使新舊版本沒有衝突。如果可能並且升級程式允許,你應該總是先卸載舊版本後再升級。
升級C++Builder
我可以保證我不為Inprise工作,也沒有得到任何利益。我無法再強調使用C++Builder的新版本的重要意義。AVs的數量尤其是設計期間的AVs在我從CB3升級至CB4(現在已經是CB5啦)後,大大減少了。同時,效能得到提升,有更多可以使用的資源。若你要長跑的話,升級是很值得的。
運行期間的AVs
儘管跟蹤是一場噩夢,運行期間的AVs是可以解決的,它們通常不是C++ Builder中所描述的bugs。在我開始幫你解決你代碼中的疑難前,你必須讀過並瞭解設計期間的AVs訊息。本部分中的建議只對運行期間的AVs起作用。尤其注意你的include目錄是否包含最新升級的庫,這往往是罪魁禍首。如果這些都不能解決你的問題,再讓我們討論編程方面,應該可以解決你的問題,讓你回到工作中去。
程式退出時發生AVs
如果你已經見過你的程式退出時,彈出的AVs對話方塊,那麼恭喜你現在象分享了許多C++Builder程式員一樣(包括我)的挫折。這類AVs是最難跟蹤的。因為debuger通常會把你引入深不可測的VCL內部或乾脆指向工程cpp檔案的後括弧。但不要害怕,下面的東西將幫你走過你的AV經曆中最壞最壞的部分。
將你的指標設為空白指標!
導致AV的一個最大的原因是嘗試刪除一個非法指標。發生的原因可能使用了一個沒有初始化的指標或試圖將東西刪除兩遍。如果你遵照如下指導,可以減少50%的AVs在您的程式中發生。對所有的指標,均如下操作:
1. 聲明指標之後,將其設為NULL。沒有這麼做的話,你不要立刻對這個指標使用new動作。否則當程式退出並執行刪除動作的話,指標的地址將變成無意義的。然後你就得到一個AV。
2. 刪除一個指標後,將其設為NULL。儘管delete動作已將記憶體清除,但它並沒有清除指標地址。如果後來又刪除一次指標的話,將導致一個AV。
記住刪除一個NULLnull 指標沒有錯,也不會帶來副作用。
使用IDE管理!
如果你建立了一個屬於(owned by)其他對象的對象,讓Owner來刪除這個對象。糊塗了?請允許我舉個例子解釋。如果你動態建立了一個panel對象,並在new方法中將它的Owner設為一個Form(Tpanel MyPanel=new Tpanel(this))。這樣當Owner(Form)被刪除時,他將嘗試刪除你的panel。如果你已經刪除了…,哇,AV。所以,任何時候當你new一個對象並在建構函式(constructor)中設定了它的Owner,不要手工刪除此對象,讓Builder來做。若你必須這樣做,確保你將它設為NULL。
在Form中使用caFree!
如果可以,不要手工刪除動態建立的form執行個體,而在其exit 事件中使用caFree.儘管這樣做並不一定解決你的存取違規(AVs)問題,但你可以分離出此原因。因為AV將發生在事件中而不是在程式退出時。
隨機AVs(非退出)
建立一個程式問題列表不僅要花很多時間,而且你所碰見的問題我很可能沒有包含在內。但這裡仍有很小一部分最常見的AV代碼問題:
o 嘗試訪問字串長度以外的位置。例如:字串是NULL空的(""),並且試圖訪問串的第一個字元myStr[1]。
o 引用一個null 指標。可能的原因有:指標應該new卻沒有new、指標在被訪問之前就已刪除、局部和全域指標同名,全域或局部指標一個new過,但另一個被訪問了。
使用者提出的更多建議
防止訪問null 指標問題的一個辦法是在決定使用指標做任何事之前總是先檢查所有的指標。可以有許多方法來實現。最好的辦法恐怕是使用assert,其實 if(myptr!=NULL) {...}的形式也不錯。值得指出的是對多層指標(multi-level),if方法同樣可以很好的工作。這要感謝C語言堅決支援在“if”謂詞的第一個假值處就跳轉(布爾賦值短路)。如:if(myptr!=NULL && myptr->itsptr!=NULL && myptr->itsptr->ptr2!=NULL) {....}
在下面的例子中
int *pArray = new int[2];
pArray[0] = 1;
pArray[1] = 2;
pArray[2] = 2; 溢出!! 數組只申請了8 bytes...
並沒有彈出通常情況下的AV對話方塊(帶紅X的那個)。而是彈出了一個不帶表徵圖的對話方塊,同時也彈出了CPU視窗。所以,當你看到類似的情況,就可以知道有數組溢出….
4190
Access Violations 存取違規(AVs)是Windows編程時發生的最麻煩的錯誤?