|
馬上注冊,結交更多好友,享用更多功能。
您需要 登錄 才可以下載或查看,沒(méi)有帳號?注冊
x
打開(kāi)EXE程序提示時(shí),提示:access violation at address xxxxxxxxx 后邊一大堆,這種情況下應該怎么解決呢?百度了一下,原來(lái)很簡(jiǎn)單
現在把解決方法公布出來(lái):
右擊“我的電腦”。單擊“屬性”。
在“系統屬性”中單擊“高級”。
在“性能”中單擊“設置”。
在“性能選項”中單擊“數據執行保護”。
單擊“添加”。選擇要運行的程序。
OK。就這么簡(jiǎn)單。
Access Violation(非法訪(fǎng)問(wèn))錯誤的解決方法
Access Violation(非法訪(fǎng)問(wèn)),General Protection Fault(一般保護性錯誤)或者Invalid Page Fault(無(wú)效頁(yè)面錯誤),雖然說(shuō)法不一樣,但本質(zhì)上總是由同一種錯誤引起的。Access Violation常常在計算機用戶(hù)運行的程序試圖存取未被指定使用的存儲區時(shí)遇到。
Access violation at address <十六進(jìn)制值>
in module <應用程序名>
Read of address <十六進(jìn)制值>
Windows用戶(hù)可能經(jīng)常會(huì )看到類(lèi)似于錯誤提示:“Error:Access violation at address 836556F8(004096da). Read of address 836556F8(00401000)”。作為一個(gè)Delphi程序開(kāi)發(fā)者,遇到這種錯誤的機會(huì )比其他用戶(hù)更多(^_^)。
一旦Windows要在它被分配的存儲區之外寫(xiě)數據信息,它就會(huì )覆蓋其他程序甚至操作系統的命令或數據。一旦發(fā)生了這種情況,操作系統將會(huì )癱瘓或者以某種形式關(guān)閉,你必須重新啟動(dòng)計算機。例如,在Windows NT/2000下一個(gè)程序遇到這種錯誤時(shí),Dr. Watson出現并且停止了該程序,捕獲了一些快速的細節狀態(tài),再把它們用文本形式記錄下來(lái)。Access Violation是某些最令人氣惱的Windows程序遇到的錯誤之一。本文的目的就是讓你找到Delphi中Access Violation的解決之道。首先聲明一點(diǎn),Access Violation和Microsoft Access沒(méi)有任何關(guān)系。
用Delphi開(kāi)發(fā)程序時(shí),我們可以把遇到的Access Violation分成兩大類(lèi):運行期和設計期。
一、設計期的Access Violation
1.硬件原因
在啟動(dòng)或關(guān)閉Delphi IDE以及編譯一個(gè)Delphi工程時(shí)容易出現設計期的Access Violation。在你的計算機運行中出現Access Violation信息可能由各種各樣的原因引起,包括系統BIOS、操作系統或者是硬件驅動(dòng)線(xiàn),有些聲卡、顯卡、網(wǎng)卡實(shí)際上也會(huì )導致這種錯誤。為什么這么說(shuō)?計算機里的每一塊卡都有它的設備驅動(dòng)程序。對于不同的制造商、不同版本的Windows或者不同版本的Delphi都可能會(huì )遇到不同的問(wèn)題。如下的幾個(gè)步驟可能有助于你解決遇到的這些問(wèn)題:
1. 按照必要的步驟來(lái)證實(shí)你安裝的驅動(dòng)程序之間沒(méi)有沖突。
2. 有時(shí)降低顯示分辨率可能會(huì )使某些古怪的顯卡驅動(dòng)程序穩定一些。
3. 如果使用雙處理器的主板,則保證對每個(gè)處理器的修改步驟一樣。
4. 對于計算機上的所有硬件注意使用最新的驅動(dòng)程序。
2.軟件原因
盡管Intel的計算機中Windows是最流行的操作系統,由于Windows系統天生的脆弱性和BUG,應用程序的誤操作可能導致操作系統的迅速癱瘓(有時(shí)操作系統本身也會(huì )莫名其妙的癱瘓)。選擇一個(gè)更穩定的程序開(kāi)發(fā)環(huán)境是解決之道,如下幾個(gè)步驟可以幫助你防止某些Access Violation的發(fā)生:
。1)盡管Windows 9X相當流行,Windows NT/2000還是從多方面被證實(shí)是一個(gè)穩定得多的環(huán)境,幾乎對于所有的Windows代碼平臺而言都是這樣。
(2) 確保對于Windows NT/2000已經(jīng)安裝了最新的service pack。每次安裝完新版的service pack,你會(huì )發(fā)現機器變得穩定了。
(3) 為你使用的各種版本的Delphi裝上當前的更新或補。˙DE、ADO……),這是提前預防錯誤的好辦法。盡量使用最新的Delphi補丁——Access Violation錯誤數量尤其是設計期的錯誤數會(huì )大大減少。
(4)如果你在IDE中經(jīng)常隨機遇到Access Violation錯誤,很有可能是你安裝了一個(gè)不好的控件、包或者一個(gè)向導,它不是你使用的版本的Delphi所編寫(xiě)或編譯的。試著(zhù)一個(gè)一個(gè)卸載定制的控件(或者包)直到問(wèn)題被解決,然后聯(lián)系控件廠(chǎng)商關(guān)注這個(gè)問(wèn)題的結果。
(5) 檢查一下計算機里是否有沒(méi)用的東西和程序沖突。奇怪的軟件程序和測試版的產(chǎn)品常常會(huì )導致Access Violation錯誤。
(6) 如果系統設置有錯誤,那么Access Violation錯誤可能也會(huì )經(jīng)常出現。如果你不停地遇到一個(gè)錯誤提示信息一樣的Access Violation,記錄下這些細節,然后通知可能導致這個(gè)錯誤的軟件制造廠(chǎng)商。
這些就是我對設計期A(yíng)ccess Violation錯誤的全部建議。
二、運行期的Access Violation
Delphi常見(jiàn)的運行期A(yíng)ccess Violation錯誤有哪些?如何防止?
任何軟件開(kāi)發(fā)都會(huì )遇到這樣的情況:你寫(xiě)好程序并測試,然后到處發(fā)送,結果用戶(hù)告訴你它失敗了。
你可能考慮用編譯指令{$D}編譯你的程序——Delphi可以建立一個(gè)有助于定位Access Violation錯誤的源代碼的鏡像文件。工程選項對話(huà)框(Project|Options|Linker & Compiler)讓你指定你所需要的一切。對于單元文件,debug信息和單元的對象代碼一起記錄在unit文件里了。編譯使用這個(gè)單元的程序時(shí),debug信息會(huì )增加單元文件的大小而且會(huì )增加額外的內存開(kāi)銷(xiāo),但是它不會(huì )影響最終可執行文件的大小和運行速度。包含debug信息和鏡像文件(Project|Options|Linker)選項的產(chǎn)品只有在{$D+} 編譯指令下才會(huì )完成行信息。
Access violation通常只在程序的某一個(gè)方面表現出來(lái)。當問(wèn)題第一次出現時(shí),考慮一下用戶(hù)進(jìn)行了什么操作是很重要的,然后從這里尋找突破口。從用戶(hù)的角度來(lái)看,你的程序中止了他們的工作,由他們來(lái)告訴你出現的問(wèn)題似乎讓你延期解決這個(gè)問(wèn)題了。然而,與用戶(hù)交流是你發(fā)現問(wèn)題和改善程序的惟一有效方法。
現在你將可以知道在只給你沖突地址的情況下,如何輕松發(fā)現準確路徑、源代碼文件、發(fā)生Access violation錯誤的行:
“Search - Find Error…”。
當一個(gè)運行期A(yíng)ccess violation出現時(shí),你的用戶(hù)得到的錯誤信息類(lèi)似于如下情況:
Access violation at address <十六進(jìn)制值>
in module <應用程序名>
Read of address <十六進(jìn)制值>
如果你的程序在Delphi IDE里包含debug信息編譯,你可以定位到導致這個(gè)錯誤源代碼這一行。
在Delphi程序中,一個(gè)最普遍導致Access Violation錯誤的原因是使用了一個(gè)沒(méi)有被創(chuàng )建的對象。如果第二個(gè)地址<十六進(jìn)制值>是FFFFFFF或0000000,十有八九就是你訪(fǎng)問(wèn)? 了一個(gè)沒(méi)有被建立的對象。例如,你調用了一個(gè)表單的事件,但這個(gè)表單不是自動(dòng)創(chuàng )建的,也沒(méi)有代碼實(shí)例化。
?procedure TfrMain.OnCreate(Sender: TObject);
var BadForm: TBadForm;
begin
//這里將會(huì )產(chǎn)生Access violation
BadForm.Refresh;
end;
假設BadForm在工程選項“Available Forms”窗口列表里——這個(gè)窗口是需要手工創(chuàng )建和釋放的。在上面的代碼里調用BadForm窗口的Refresh方法就會(huì )導致Access violation。
如果你在Debugger選項窗口使“Stop on Delphi Exceptions”生效,那么就會(huì )彈出下面的信息:
The message states that the EAccessViolation has occurred. The EAccessViolation is the exception class for invalid memory access errors.
這是你在設計程序時(shí)將會(huì )看到的信息,下一個(gè)信息框將會(huì )出現,然后程序失敗了:
Access violation at address 0043F193
in module ’Project1.exe’
Read of address 000000.
第一個(gè)十六進(jìn)制數0043F193是發(fā)生Access violation的編譯代碼(Project1.exe)的運行期錯誤的地址。在IDE里選擇菜單項“Search|Find Error…”,在對話(huà)框里輸入錯誤發(fā)生的地址(0043F193)后點(diǎn)擊“OK”按鈕。Delphi將會(huì )重新編譯你的工程文件,然后顯示發(fā)生運行期錯誤的那一行代碼,這里就是BadForm.Refresh這一行了。
下面列出了Delphi環(huán)境下導致Access violation錯誤的大部分常見(jiàn)原因。這個(gè)列表不是也不可能覆蓋所有可能出現的Access violation的情況。請在論壇上發(fā)送你的Access violation信息,大家可以試著(zhù)一起解決這個(gè)問(wèn)題——真正的實(shí)際事例一般情況下比列出來(lái)的錯誤隱晦得多。
1. 調用一個(gè)不存在的對象
如上所述,大部分Access violation的合理原因是使用了沒(méi)有被創(chuàng )建或者已經(jīng)被釋放的對象。為了防止這種類(lèi)型的Access violation的發(fā)生,請確保你訪(fǎng)問(wèn)的任何對象都首先被創(chuàng )建了。例如,當一個(gè)Table定位在一個(gè)沒(méi)有被創(chuàng )建的data module(從auto-crete窗口里移走了)里,你可能在窗體的OnCreate事件里打開(kāi)這個(gè)表。
在下面的代碼里,在調用一個(gè)已經(jīng)被刪除了的對象(b:TBitmap)事件后,一個(gè)Access violation出現了:
var b:TBitmap;
begin
b:=TBitmap.Create;
try
//對b對象進(jìn)行一些操作
finally
b.free;
end;
...
//由于b已經(jīng)被釋放,一個(gè)Access violation錯誤將會(huì )出現
b.Canvas.TextOut(0,0,’這是一個(gè) Access Violation’);
end;
2. 不存在的API參數
如果你試圖給Win API函數傳遞一個(gè)不存在的參數將會(huì )出現一個(gè)Access violation錯誤。解決此類(lèi)Access violation錯誤的最好方法是查閱Win API幫助,看看這個(gè)API函數調用的參數信息以及參數類(lèi)型。例如,總是保證不給一個(gè)緩沖參數傳遞一個(gè)無(wú)效指針。
3. 讓Delphi釋放
當一個(gè)對象擁有另一個(gè)對象時(shí),讓它給你做刪除工作。因為默認情況下,所有的窗體(自動(dòng)創(chuàng )建的)都屬于A(yíng)pplication對象。當一個(gè)應用程序結束時(shí),它釋放了Application對象,也就釋放了所有窗體。例如,如果你在程序開(kāi)始時(shí)自動(dòng)創(chuàng )建了兩個(gè)窗體(Form1/Unit1和Form2/Unit2),下面的代碼就會(huì )導致Access violation錯誤的出現:
unit Unit1;
...
uses unit2;
...
procedure TForm1.Call_Form2
begin
Form2.ShowModal;
Form2.Free;
//Access violation錯誤將會(huì )出現
Form2.ShowModal;
end;
4. 殺死異常
永遠不要破壞臨時(shí)異常對象(E),處理一個(gè)異常會(huì )自動(dòng)釋放異常對象。如果你自己手動(dòng)釋放了異常對象,程序會(huì )試圖再次釋放它,那么就會(huì )出現Access violation錯誤:
Zero:=0;
try
dummy:= 10 / Zero;
except
on E: EZeroDivide do
MessageDlg(’不能用0做除數!’,mtError, [mbOK], 0);
E.free. ////Access violation錯誤將會(huì )出現
end;
5. 檢索一個(gè)空字符串
一個(gè)空字符串是沒(méi)有任何數據的。就是說(shuō),檢索一個(gè)空字符串相當于訪(fǎng)問(wèn)一個(gè)不存在的對象,這將導致Access violation錯誤:
var s: string;
begin
s:=’’;
s[1]:=’a’;
//Access violation錯誤將會(huì )出現
end;
6. 直接引用指針
你必須間接引用指針,否則你會(huì )改變指針地址并可能會(huì )破壞其他存儲單元 :
procedure TForm1.Button1Click(Sender: TObject);
var
p1 : pointer;
p2 : pointer;
begin
GetMem(p1, 128);
GetMem(p2, 128);
//下一行導致Access violation錯誤
Move(p1, p2, 128);
//下一行方法正確
Move(p1^, p2^, 128);
FreeMem(p1, 128);
FreeMem(p2, 128);
end;
這些就是我對運行期A(yíng)ccess Violation錯誤的全部建議,我希望你們也能對你們程序出現的Access Violation錯誤提出一些看法 |
|