2012-04-11 105 views
8

我似乎無法找出這一個。我的程序編譯並運行成功,但在調試期間,只有在關閉程序時彈出一個消息框,提示「無效的指針操作」。我精心檢查了所有FormCloseQuery和FormDestory事件,以查找任何語法或邏輯錯誤。我沒有發現,他們按預期執行沒有任何錯誤。無效指針操作 - 德爾福XE

enter image description here

當我告訴編譯器在無效指針操作錯誤打破,它不會做任何事情,但掛斷程序。在這一點上,我不得不終止或殺死這個過程。

你如何看出這一點?

由於提前,

+6

啓用調試DCU並逐步關閉,直到找到觸發此錯誤的內容。您是否在Full Debug模式下運行FastMM? – 2012-04-11 20:09:34

+0

@DavidHeffernan,:)我記得我們有一個關於FastMM的對話。不幸的是,我還沒有使用FastMM,因爲我在測試時會跑回去。我將啓用DCU並查看會發生什麼。 – ThN 2012-04-11 20:16:54

+0

@DavidHeffernan,在啓用了dcu之後,調試器停止在System.pas文件中。有點混亂,但我認爲它是因爲梅森惠勒的原因之一。我想現在我必須把FastMM放回去。 – ThN 2012-04-12 12:30:17

回答

25

無效指針異常是由內存管理器拋出的時候,它會釋放無效的內存。有三種方式可以發生。

最常見的是因爲您試圖釋放已釋放的對象。如果打開FastMM的FullDebugMode,它會檢測到這一點並直接指出問題所在。 (但是一定要建立一個地圖文件,這樣它就可以得到所需要的信息來創建有用的堆棧跟蹤。)

第二種方法是,如果您試圖釋放分配給內存管理器以外的內存。在將DELPHI EXE中的字符串傳遞給未使用共享內存管理器功能的Delphi DLL時,我已經看到過這幾次。

而第三種方式是直接用指針搞亂並可能不適用於你。如果您嘗試使用FreeMemDispose一個不指向FastMM分配的實際內存塊的錯誤指針,則會出現此錯誤。

這很可能是第一個。使用FullDebugMode,您可以輕鬆找到問題的根源。

+0

你是絕對正確的。你的第一個原因是爲什麼我的程序正在提出這個異常通知。然而,它正在升高,因爲我的TForm的摧毀事件被稱爲不止一次。我不明白爲什麼。 – ThN 2012-04-12 15:10:10

+0

如果我要猜測,我會說因爲您的表單是由一個所有者創建的(例如Application;您是否使用'Application.CreateForm'來構造它?),然後在其他地方嘗試釋放它手動。看看它被釋放的兩次堆棧軌跡;他們會給你一個想法是怎麼回事。記住[單一所有權原則](http://tech.turbu-rpg.com/106/delphi-memory-management-made-simple):您的表單可以由應用程序或您的代碼擁有,但不是兩者都有。 – 2012-04-12 16:19:08

0

在Delphi調試過程中,我被這種「指示錯誤」所捕獲。

檢查,如果你有,嘗試表明,可能未初始化在同一單位(或全球)其他變量啓用「允許函數調用」或手錶任何觀看變量。在停止斷點時,可能會導致Delphi的調試器嘗試通過訪問未初始化的指針或變量的函數調用來顯示該值。導致AV的實際變量我甚至不在您的監視列表中。當你告訴德爾福內存管理器來釋放不屬於它的內存出現

+3

EAccessViolation與EInvalidPointer不同。 *訪問*無效指針給前者;只有*釋放*給後者。 – 2013-01-18 15:35:07

9

無效的指針操作。有三種方式可能發生:

  • 釋放已被釋放的指針或對象。
  • 使用FreeMem釋放某些其他內存管理器分配的內容(如GlobalAllocCoTaskMemAlloc)。
  • 釋放未初始化的指針。 (這與釋放空指針截然不同,這是完全安全的。)

在程序的某個地方,您正在執行這些操作之一。調試器檢測到內存管理器拋出的異常,所以做一些調試。從堆棧跟蹤中,你應該能夠看到你試圖釋放哪個變量。檢查你的程序的其餘部分是否使用了該變量的其他方式。

像MadExcept和Eureka Log這樣的工具可以幫助您找到雙免費錯誤。他們可以跟蹤問題指針的分配位置以及第一次釋放的位置,這有時可以幫助您找出錯誤並停止多次釋放事件。

+0

如果嘗試釋放本地聲明的對象的地址,是否也會拋出它? – Wolf 2015-01-13 09:17:49

+0

是的,@狼。這是第二個要點。在這種情況下,你會試圖釋放分配給堆棧的內存。 – 2015-01-13 13:18:45

+0

謝謝。這個「分配」或「內存管理器」在討論自動變量時看起來很奇怪。也許這應該被添加(以更明確的方式)? – Wolf 2015-01-13 13:22:15

1

第四個原因是指針操作無效。我有兩個指針,其中真正的數組[0..1000]和第三個指針是真實數組[1..200]。所有3個指針在初始化爲 (對於i:= 0到1000) 開始 ptr1^[i]:= 0; ptr2^[i]:= 0; ptr3^[i]:= 0; 結束; 雖然這個糟糕的編程沒有打擾Delphi中的Pascal,但是調用Dispose這3個指針中的任何一個導致無效指針操作。該修復只是爲了正確初始化第三個指針。