2013-02-17 52 views
2

我有一個將所有動態創建的數據模塊加載到TList中的應用程序。應用程序在Windows XP操作系統下運行。從應用程序關閉按鈕關閉應用程序時,代碼正確執行。但是,當從任務欄菜單關閉應用程序時,會引發無效指針操作。以不同方式關閉應用程序時,相同的代碼行爲會有所不同。德爾福 - 從任務欄菜單關閉應用程序時出現無效指針操作

負責破壞數據模塊

for iPos := 0 to FDatamodules.Count - 1 do //FDataModules is of type TList 
    if FDatamodules.Items[iPos] <> nil then 
     TDatamodule(FDatamodules.Items[iPos]).Free; 

且堆棧

:7c812a6b kernel32.RaiseException + 0x52 
System.TObject.FreeInstance 
System.ErrorAt(2,$4A7FEFC) 
System.Error(reInvalidPtr) 
System.TObject.FreeInstance 
System._ClassDestroy(???) 
Classes.TDataModule.Destroy 
System.TObject.Free 
RBAFORM.TRBABaseForm.Destroy 

LE的代碼:似乎從任務欄菜單關閉應用正在發送一個HALT(0)到應用程序並且數據模塊被釋放。在下圖中:左邊是正常關閉操作的堆棧,右邊是任務欄菜單中關閉應用程序的堆棧。

enter image description here

+6

如何創建數據模塊?創建(無)應該是正確的方法。 – 2013-02-17 11:07:14

+0

@LURD - 我不明白爲什麼這個代碼在關閉應用程序關閉按鈕時運行,但是當從任務欄菜單關閉它時崩潰。執行相同的代碼,但從任務欄菜單關閉時會崩潰。 – RBA 2013-02-17 13:24:21

+1

這可能是David解釋的,取決於數據模塊被釋放時的順序。如果您首先手動銷燬數據模塊,那麼可以,但另一種方式並不正確。可能會有首先出現的競爭狀況。 – 2013-02-17 13:28:11

回答

7

這似乎是一個雙重釋放的問題(如LU你就此問題發表意見),這意味着你更然後一旦釋放你的數據模塊的一個實例。

當您使用Create(nil)創建實例時,它不屬於任何人,您可以放心地致電Free。 (另請參閱What is the meaning of nil owner in component constructor

如果使用Create(Form1)(非零參數)創建它,則不再需要致電Free。在本例中,當Form1被釋放時它將被自動釋放。

要確定發生了什麼,應該在FullDebugMode中使用FastMM或類似的內存調試器。內存調試器應該能夠發現問題併爲您提供更多有用的信息。

+2

如果您創建了一個擁有的組件,那麼手動釋放它仍然可以。它會通知所有者將其從其擁有的組件列表中刪除。但是,如果擁有者首先出現故障,那麼可能是無效的指針操作。 +1 – 2013-02-17 13:21:03