呼叫abort後,在退出程式時有時會顯示記憶體存取衝突之錯誤錯誤? |
答題得分者是:aftcast
|
ry_lee
高階會員 發表:368 回覆:251 積分:123 註冊:2002-03-19 發送簡訊給我 |
在某條件成立時呼叫Abort或Exit以中段程式執行流程,但如在下列情況可能非用abort不可,如在某程式區塊之code中當第一函數檢查條件成立時,即不呼叫第二函數及其後程式碼
procedure TfrmMain.Button5Click(Sender: TObject); begin fun1; fun2; showmessage('check success'); end; fun1之code: if 條件符合時 then exit; 那麼會接著呼叫fun2及showmessage('check success'); 但如果fun1之code: if 條件符合時 then abort; 那麼之後fun2,及showmessage('check success');皆不執行 當我在測試程式(是以abort;來中斷流程),可少寫很多程式碼,但在退出程式偶而會發生這錯誤訊息 "錯誤訊息 access violation at address 004037EC in module ' project1.exe'. Read of address FFFFFFFD" 請問是否是呼叫 abort 之關係?是否改為呼叫 exit 較不會發生這問題? |
smallfox
高階會員 發表:2 回覆:113 積分:128 註冊:2003-02-19 發送簡訊給我 |
|
smallfox
高階會員 發表:2 回覆:113 積分:128 註冊:2003-02-19 發送簡訊給我 |
|
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
|
ry_lee
高階會員 發表:368 回覆:251 積分:123 註冊:2002-03-19 發送簡訊給我 |
謝謝 smallfox ,GrandRURU先進寶貴的回覆,fun1,fun2其實是procedure,當然改成fun也可以,fun1之內容只是很簡單的code如下:
if edit1.text='' or edit2.text='' then begin showmessage('欄位不能是空白'); abort; end; 只是以前許多程式都會用到abort也不曾出現過什麼問題,現在怎麼會出現這問題,不曉得是程式或硬體之問題,因為以前是在pc上run,現在是在NB上run? ===================引 用 GrandRURU 文 章=================== 所以的確是Abort的問題?? 因為有些function底下仍是要做DataSet的工作,有時會需要在function內做abort處理,我也常遇到記憶體存取錯誤的怪問題,明明該釋放的都釋放了 Abort,真的會是它的問題嗎??? ===================引 用 smallfox 文 章=================== 我的經驗是: Abort 應使用在 "事件" 類的程序內較不會出錯, 而非使用在 function 內. |
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
不知道把CodeGuard開啟後是否能抓到這類的error
===================引 用 ry_lee 文 章=================== 謝謝 smallfox ,GrandRURU先進寶貴的回覆,fun1,fun2其實是procedure,當然改成fun也可以,fun1之內容只是很簡單的code如下: if edit1.text='' or edit2.text='' then begin showmessage('欄位不能是空白'); abort; end; 只是以前許多程式都會用到abort也不曾出現過什麼問題,現在怎麼會出現這問題,不曉得是程式或硬體之問題,因為以前是在pc上run,現在是在NB上run? |
RootKit
資深會員 發表:16 回覆:358 積分:419 註冊:2008-01-02 發送簡訊給我 |
|
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
我只是不想讓例外訊息跳出而已
而我的程式碼看起來像是這樣: [code cpp] 事件或函式() { ...... try{ try{ } catch(...){ Abort(); } ...... } __finally{ } return 0; } [/code] 這樣不算嚴謹……嗎? ===================引 用 RootKit 文 章=================== 通常會有這樣的問題,可能是因 Abort 會造成 事件或父元件(Form)因釋放時,指向無效的位址。 使用 Abort 要嚴謹的,因為中斷的事後所有復原的程序。有可能這些動作是隱藏在 VCL 內,既使您本身用的都有釋放掉。 絕對的建議您使用 Exit 取代 Abort 利用 Fun 回傳成功或失敗來過濾,才是嚴謹的程式碼。 |
RootKit
資深會員 發表:16 回覆:358 積分:419 註冊:2008-01-02 發送簡訊給我 |
|
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
個人覺得,依照樓主想達成的目的,真的不應該使用Abort。建議你還是照rootkit的說法來寫程式。
要知道,Abort它真正的意函是「中斷並產生一個例外處理」,換句話說,你該去處理這個例外處理函式。你應該配套 try except (<layer id="google-toolbar-hilite-0" ="background-color: Yellow; color: black;" id="google-toolbar-hilite-0">delphi</layer></layer>語法),在except 中使用on E: Exception do …來做你想要的事。如果不想在這裡寫,那也要在TApplication::HandleException裡來處理。 GrandRuRu,在c 裡,在catch(…)中,只要空白,什麼也沒寫…就可以達到好像什麼都沒發生,而不是用Abort,否則它會在產生一次異常。 如果說,樓主只是想"偷懶"少寫,那<layer ="background-color: Cyan; color: black;" id="google-toolbar-hilite-8">exit</layer> 或是abort,都應該要注意是否該處理的,該放的,該設定值的…等等等的問題都確認後才<layer ="color: rgb(51, 102, 255);"><br />剛突然想到…問題極可能是…你沒有自己寫相對的例外處理,而可能導致它上層的某元件之類的接到,做了該元件認為要處理的例外處理,而事實上這個例外並非是該元件產生,而是你自己產生出來的,所以就亂指一通…產生了AV。例外處理是會往上層一直轉,直到有對到例外處理。所以啦,這個Abort還是不會亂用的好,除非自己去handle,而不是座視不管讓它往上轉到不該轉的地方做了例外處理。我認為你原來的實做,不單純只是showmessage,一定是有許多的元件的操作,所以亂了! Abort的函式實作如下: 請參考一下 procedure Abort; function ReturnAddr: Pointer; asm MOV EAX,[EBP 4] end; begin raise EAbort.Create(SOperationAborted) at ReturnAddr; end;
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2010-12-31 01:29:37, 註解 無‧
|
ry_lee
高階會員 發表:368 回覆:251 積分:123 註冊:2002-03-19 發送簡訊給我 |
affcast你好:
我的程式中有TApplication::HandleException,而fun1的code真的如下簡單, if edit1.text='' or edit2.text='' then begin showmessage('欄位不能是空白'); abort; end; 因為不想在許多button及mainmenu之"onclick"內寫 if edit1.text='' or edit2.text='' then begin showmessage('欄位不能是空白'); exit; end; 所以才會寫fun1,不過聽你及其他先進的說法,我覺得很有道理,會盡可能不用abort,改用exit. ===================引 用 aftcast 文 章=================== 個人覺得,依照樓主想達成的目的,真的不應該使用Abort。建議你還是照rootkit的說法來寫程式。 要知道,Abort它真正的意函是「中斷並產生一個例外處理」,換句話說,你該去處理這個例外處理函式。你應該配套 try except (<layer id="google-toolbar-hilite-0" ="background-color: yellow; color: black"></layer>delphi語法),在except 中使用on E: Exception do …來做你想要的事。如果不想在這裡寫,那也要在TApplication::HandleException裡來處理。 GrandRuRu,在c 裡,在catch(…)中,只要空白,什麼也沒寫…就可以達到好像什麼都沒發生,而不是用Abort,否則它會在產生一次異常。 如果說,樓主只是想"偷懶"少寫,那<layer id="google-toolbar-hilite-7" ="background-color: cyan; color: black"></layer>exit 或是abort,都應該要注意是否該處理的,該放的,該設定值的…等等等的問題都確認後才<layer id="google-toolbar-hilite-9" ="color: rgb(51,102,255)"><br />剛突然想到…問題極可能是…你沒有自己寫相對的例外處理,而可能導致它上層的某元件之類的接到,做了該元件認為要處理的例外處理,而事實上這個例外並非是該元件產生,而是你自己產生出來的,所以就亂指一通…產生了AV。例外處理是會往上層一直轉,直到有對到例外處理。所以啦,這個Abort還是不會亂用的好,除非自己去handle,而不是座視不管讓它往上轉到不該轉的地方做了例外處理。我認為你原來的實做,不單純只是showmessage,一定是有許多的元件的操作,所以亂了! Abort的函式實作如下: 請參考一下 procedure Abort; function ReturnAddr: Pointer; asm MOV EAX,[EBP 4] end; begin raise EAbort.Create(SOperationAborted) at ReturnAddr; end; |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |