在用delphi XE5編程時遇到以下問題:編程
Exception EInvalidPointer in module Project1.exe at 00007595.數組
Invalid pointer operation.函數
從描述上來看,是指針使用錯誤引發的。我並沒用使用太多指針變量,我首先檢查了一下動態數組(事實上動態數組在SetLength後,即便越界了,也不會報錯),發現沒有問題。因而我是用Debug調試。出現以下窗口:spa
點擊 Break,跳到了這裏:指針
1 procedure TObject.FreeInstance; 2 begin 3 CleanupInstance; 4 _FreeMem(Pointer(Self)); 5 end;
箭頭指向第四行。調試
圖片以下:code
看到FreeMem,我想到本身建立過一個TFont類的一個對象。orm
代碼以下:對象
1 Ofont:=TFont.Create(); 2 OFont:=Canvas.Font; 3 Canvas.Font.Name:='微軟雅黑'; 4 Canvas.Font.Style:=[fsBold]; 5 Canvas.Font.Color:=clBlack; 6 Canvas.Font.Height:=40; 7 tempint:=(Form1.ClientWidth-Canvas.TextWidth('XXXXXXXX') ) div 2; 8 Canvas.TextOut(tempint,3,'XXXXXXXX'); 9 Canvas.Font:=OFont; 10 OFont.Free;
而後我將第10行的語句註釋掉後,異常就消失了。果真問題出在這。blog
可是新的問題又來了,一個對象建立了難道不該該Free嗎?在百度上查了一番後,才知道:
使用這種方式建立對象,
Ofont:=TFont.Create();
能夠不Free,函數執行完後,會自行Free。不過最好Free。並且最好使用try語句。可是我這裏爲何不能Free呢?
實際上是一個關於對象複製的知識我沒有搞懂。對象名,就是一個指針。使用:
OFont:=Canvas.Font;
實際上是將Canvas.Font的指針賦值給了OFont,
OFont.Free;
這個語句實際上也在釋放Canvas.Font。Canvas.Font是由系統管理的,這裏不該該釋放,否者就出現已釋放的指針再進行釋放。
我這段代碼也沒有起到「保護現場」的做用。應該使用:
1 Ofont.Assign(Canvas.Font); //將原始值保留
來複制對象的值來達到保護現場的做用。代碼修改後以下:
procedure TForm1.InitFormUI(); {*功能:在窗體上方居中顯示 「XXXXXXXX」} var tempint:integer; Ofont:TFont; begin {* Ofont不添加 free語句,程序異常消失 - *異常爲:(delphi Exception EAccessVioation in module Project1)} Ofont:=TFont.Create(); Ofont.Assign(Canvas.Font); //將原始值保留 Canvas.Font.Name:='微軟雅黑'; Canvas.Font.Style:=[fsBold]; Canvas.Font.Color:=clBlack; Canvas.Font.Height:=40; tempint:=(Form1.ClientWidth-Canvas.TextWidth('XXXXXXXX') ) div 2; Canvas.TextOut(tempint,3,'XXXXXXXX'); Canvas.Font.Assign(OFont); //恢復爲原始值 OFont.Free; end;