Delphi Access Violation错误的分析

转自:http://www.cnblogs.com/delphi7456/archive/2010/11/13/1876180.htmlDelphi Access Violation错误的分析

      Delphi常见的运行期Access Violation错误有哪些?如何防止?

      任何软件开发都会遇到这样的情况:你写好程序并测试,然后到处发送,结果用户告诉你它失败了。

      你可能考虑用编译指令{$D}编译你的程序——Delphi可以建立一个有助于定位Access Violation错误的源代码的镜像文件。工程选项对话框(Project|Options|Linker & Compiler)让你指定你所需要的一切。对于单元文件,debug信息和单元的对象代码一起记录在unit文件里了。编译使用这个单元的程序时,debug信息会增加单元文件的大小而且会增加额外的内存开销,但是它不会影响最终可执行文件的大小和运行速度。包含debug信息和镜像文件(Project|Options|Linker)选项的产品只有在{$D+} 编译指令下才会完成行信息。

  Access violation通常只在程序的某一个方面表现出来。当问题第一次出现时,考虑一下用户进行了什么操作是很重要的,然后从这里寻找突破口。从用户的角度来看,你的程序中止了他们的工作,由他们来告诉你出现的问题似乎让你延期解决这个问题了。然而,与用户交流是你发现问题和改善程序的惟一有效方法。

  现在你将可以知道在只给你冲突地址的情况下,如何轻松发现准确路径、源代码文件、发生Access violation错误的行: “Search - Find Error…”。

  当一个运行期Access violation出现时,你的用户得到的错误信息类似于如下情况:
Access violation at address <十六进制值> in module <应用程序名> Read of address <十六进制值>

  如果你的程序在Delphi IDE里包含debug信息编译,你可以定位到导致这个错误源代码这一行。 在Delphi程序中,一个最普遍导致Access Violation错误的原因是使用了一个没有被创建的对象。如果第二个地址<十六进制值>是FFFFFFF或0000000,十有八九就是你访问? 了一个没有被建立的对象。例如,你调用了一个表单的事件,但这个表单不是自动创建的,也没有代码实例化。

procedure TfrMain.OnCreate(Sender: TObject);
var BadForm: TBadForm;
begin
//这里将会产生Access violation
BadForm.Refresh;
end;

  假设BadForm在工程选项“Available Forms”窗口列表里——这个窗口是需要手工创建和释放的。在上面的代码里调用BadForm窗口的Refresh方法就会导致Access violation。

  如果你在Debugger选项窗口使“Stop on Delphi Exceptions”生效,那么就会弹出下面的信息: The message states that the EAccessViolation has occurred. The EAccessViolation is the exception class for invalid memory access errors. 

  这是你在设计程序时将会看到的信息,下一个信息框将会出现,然后程序失败了: Access violation at address 0043F193 in module ’Project1.exe’ Read of address 000000.

  第一个十六进制数0043F193是发生Access violation的编译代码(Project1.exe)的运行期错误的地址。在IDE里选择菜单项“Search|Find Error…”,在对话框里输入错误发生的地址(0043F193)后点击“OK”按钮。Delphi将会重新编译你的工程文件,然后显示发生运行期错误的那一行代码,这里就是BadForm.Refresh这一行了。

  下面列出了Delphi环境下导致Access violation错误的大部分常见原因。这个列表不是也不可能覆盖所有可能出现的Access violation的情况。请在论坛上发送你的Access violation信息,大家可以试着一起解决这个问题——真正的实际事例一般情况下比列出来的错误隐晦得多。

1. 调用一个不存在的对象
  如上所述,大部分Access violation的合理原因是使用了没有被创建或者已经被释放的对象。为了防止这种类型的Access violation的发生,请确保你访问的任何对象都首先被创建了。例如,当一个Table定位在一个没有被创建的data module(从auto-crete窗口里移走了)里,你可能在窗体的OnCreate事件里打开这个表。
  在下面的代码里,在调用一个已经被删除了的对象(b:TBitmap)事件后,一个Access violation出现了:
var b:TBitmap;
begin
b:=TBitmap.Create;
try
//对b对象进行一些操作
finally
b.free;
end;
...
//由于b已经被释放,一个Access violation错误将会出现
b.Canvas.TextOut(0,0,’这是一个 Access Violation’);
end;

2. 不存在的API参数
  如果你试图给Win API函数传递一个不存在的参数将会出现一个Access violation错误。解决此类Access violation错误的最好方法是查阅Win API帮助,看看这个API函数调用的参数信息以及参数类型。例如,总是保证不给一个缓冲参数传递一个无效指针。

3. 让Delphi释放
  当一个对象拥有另一个对象时,让它给你做删除工作。因为默认情况下,所有的窗体(自动创建的)都属于Application对象。当一个应用程序结束时,它释放了Application对象,也就释放了所有窗体。例如,如果你在程序开始时自动创建了两个窗体(Form1/Unit1和Form2/Unit2),下面的代码就会导致Access violation错误的出现:
unit Unit1;
...
uses unit2;
...
procedure TForm1.Call_Form2
begin
Form2.ShowModal;
Form2.Free;
//Access violation错误将会出现
Form2.ShowModal;
end;

4. 杀死异常
  永远不要破坏临时异常对象(E),处理一个异常会自动释放异常对象。如果你自己手动释放了异常对象,程序会试图再次释放它,那么就会出现Access violation错误:
Zero:=0;
try
dummy:= 10 / Zero;
except
on E: EZeroDivide do
MessageDlg(’不能用0做除数!’,mtError, [mbOK], 0);
E.free. ////Access violation错误将会出现
end;

5. 检索一个空字符串
  一个空字符串是没有任何数据的。就是说,检索一个空字符串相当于访问一个不存在的对象,这将导致Access violation错误:
var s: string;
begin
s:=’’;
s[1]:=’a’;
//Access violation错误将会出现
end;

今天我遇到的Access Violation错误就是由于检索一个空字符串造成的

if aModalArray[i].HelpKeyword=‘背景‘ then
cbbNewParent.Items.Add(aModalArray[i].Caption);

当aModalArray[i].HelpKeyword=’’的时候就引发了异常

避免的方法是先对aModalArray[i].HelpKeyword是否为空进行判断

6. 直接引用指针
你必须间接引用指针,否则你会改变指针地址并可能会破坏其他存储单元 :
procedure TForm1.Button1Click(Sender: TObject);
var
p1 : pointer;
p2 : pointer;
begin
GetMem(p1, 128);
GetMem(p2, 128);
//下一行导致Access violation错误
Move(p1, p2, 128);
//下一行方法正确
Move(p1^, p2^, 128);
FreeMem(p1, 128);
FreeMem(p2, 128);
end;
  这些就是我对运行期Access Violation错误的全部建议,我希望你们也能对你们程序出现的Access Violation错误提出一些看法。
  相信所有读者都遇到过“Access violation” 的错误,如果不是自己的程序,我们有很多人就把责任都推在Bill Gates的头上。如果你自己的程序出现了这个尴尬的错误,面对用户的询问,我们该如何解释?本文就是最好的答案。
时间: 2024-10-08 06:55:32

Delphi Access Violation错误的分析的相关文章

&quot;Unhandled exception in app.exe (QtGuid4.dll): 0xC0000005: Access Violation&quot;错误解决

本文要解决的Qt调试问题截图如下: 起因:在代码中添加类型为QColor的二维数组,存储图片每个像素. 现象:调试时出现上图所示错误. 原因:经过百度以及反复查看代码,发现在代码中,有数组越界的情况.因为定义的时候,数组的两个维度大小不一样,而在实 现 QWidget的重画事件时,因为坐标系的差别,使得两个维度的顺序对换,使得发生数组越界的情况. 详细解释:在程序中我定义的数组是QColor color [ Height ] [ Width ], 我的本意是Height代表图片的高度,Heigh

php has encountered an access violation

今天服务器装系统,配置完php环境后连接数据库包php has encountered an access violation错误: 环境: win2008 R2 php 5.2.9 IIS7 mysql 5.1 采用isapi方式配置 调试很长时间没有解决,最后采用fastcgi方式解决.

Delphi 在写Ini文件时报错,Access violation at address 774D6EC8 in module &#39;ntdll.dll&#39; write of address 004044CD

检查代码发现读写Ini文件函数ReadString参数错误导致:如下 节点不能为空. Delphi 在写Ini文件时报错,Access violation at address 774D6EC8 in module 'ntdll.dll' write of address 004044CD

关于错误Access Violation和too many consecutive exceptions 解决方法

关于错误Access Violation和too many consecutive exceptions 解决方法 “如果DLL中用到了DELPHI的string类型,则DLL和主程序中都需要加上ShareMem”.DLL项目加ShareMem这个我知道,但主程序中也要加?这我就不明白了,为什么以前不加的时候没这个问题呢?加就加吧,果然加上后一点问题都没有.唉,真是搞不明白.最后在新建DLL项目时,DELPHI有一段注释给了我答案. library MyDll; { Important note

AD09 &quot;Access violation at address 0C241A06 in module &#39;IntegratedLibrary.DLL&quot; 错误解决办法

regedit-将HKEY_CURRENT_USER\Software\AltiumDesignerWinter09\DesignExplorer\Preferences\IntegratedLibrary\Loaded Libraries下面的所有内容删除,重新打开altium designer添加库即可. AD09 "Access violation at address 0C241A06 in module 'IntegratedLibrary.DLL" 错误解决办法

“access violation at address xxxxxxxxx”错误

        在进行磁盘整理的时候,打开Foxmail的时候出现了"access violation at address32383137"错误 和"access violation at address00000000"错误.在查资料的时候遇到很多Access Violation(非法访问)的错误,那这里就统称为"access violation at address xxxxxxxxx"错误. 如图所示:   1,原理          这

解决 “access violation at address xxxxxxxxx”错误

在进行磁盘整理的时候,打开Foxmail的时候出现了"access violation at address32383137"错误 和"access violation at address00000000"错误.在查资料的时候遇到很多Access Violation(非法访问)的错误,那这里就统称为"access violation at address xxxxxxxxx"错误. 如图所示: 1,原理         这个问题是关于Acces

First-chance exception at 0x782260ec in xxx.exe: 0xC0000005: Access violation

开发的软件可以通过按钮创建子窗体,在win7下测试正常,在winXP下崩溃.于是搜到以下帖子,没有讲到直接解决方法,因为貌似没有直接解决的方式. 通过里边的设置可以捕获异常,然后再分析代码. 原帖地址 'First-chance exception' usually means an exception that has been handled by user code. If you're using the Vosual Studio & the Windows Mobile emulat

当应用出现 access violation at address in module时

Delphi2010和XE10,midas是不同的版本,之前开发的两个系统,基于不同的Delphi版本,经常出现access violation at address in module错误.特别是当midas用的是低版本时,用XE10进行datasnap进行连接时会出现该错误,刚开始不知道为什么,搞了老半天,现在清楚了,以后要注意哦!!!