Access Violations 訪問沖突(AVs)是Windows編程時發生的最麻煩的錯誤?
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。
記住刪除一個NULL空指針沒有錯,也不會帶來副作用。
使用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 引用一個空指針。可能的原因有:指針應該new卻沒有new、指針在被訪問之前就已刪除、局部和全局指針同名,全局或局部指針一個new過,但另一個被訪問了。
用戶提出的更多建議
防止訪問空指針問題的一個辦法是在決定使用指針做任何事之前總是先檢查所有的指針。可以有許多方法來實現。最好的辦法恐怕是使用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窗口。所以,當你看到類似的情況,就可以知道有數組溢出….
https://blog.csdn.net/cker/article/details/4190
Access Violations 訪問沖突(AVs)是Windows編程時發生的最麻煩的錯誤?