在用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;