编译的时候没错,运行EXE文件也大部分时候正常没错,就是偶尔会窜出个这个错误提示来,出现这个的几率非常小,真是无从下手了,估计是什么原因?还有就是如何能找出出错的地方??

解决方案 »

  1.   

    FastMM, Eurakalog等工具
    不过看提示,这不一定是内存泄露问题,应当是非法访问错误
      

  2.   

    程序里有没有使用线程?如果使用了线程,那重点检查一下线程的运行逻辑和同步。有时候A线程依赖B线程里的对象,但B线程先于A线程被释放了,那么A线程就会出AV。而如果你没有控制线程的同步问题,因为线程释放的顺序不确定,所以这个错误有时候会出来有时候又没有。
      

  3.   

    首先给你明确,AV错误不是内存泄露,一般是访问了非法内存导致的。内存泄露通常是没错误的(除非已经out of memory了)
      

  4.   

    另外还有一个地方要查,就是全局对象的释放。检查一下释放全局对象的代码,看看是否有代码在对象释放后还在访问全局对象。这里我曾经遇到一个很无趣的例子:
    type
      TTestForm = class(TForm)
        procedure TestFormCreate(Owner: TObject);
        procedure TestFormDestroy;
      private
        FChildForm: TMyChildForm;
      end;implement
      procedure TTestForm.TestFormCreate(Owner: TObject);
      begin
        Application.CreateForm(TMyChildForm, FChildFomr);  // 这句会造成问题
        // 如果在OnDestroy中自己释放FChildForm,不能用下面这句,而应该用
        // FChildForm := TMyChildForm.Create(nil);  //注意Owner是nil
        // 注意写成FChildForm := TMyChildForm.Crate(self);也是错误的
        // 因为如果你用Application.CreateForm或者TMyChildForm.Create(self)
        // 都会把主窗口设置成子窗口的Owner
        // 而根据VCL的设计,Owner在销毁时会自动释放自己所有的Child
        // 但是你已经在OnDestroy里面销毁了对象,所以自动发生的自动销毁会造成AV错误
      end;  procedure TTestForm.TestFormDestroy;
      begin
        FreeAndNil(FChildForm);
      end;
      

  5.   

    谢谢老师们的提醒,我这里有这种情况,不知道是不是问题在这里:(出错的时候是在Form1上)我的程序有两个表单,Form1(Unit1),Form2(Unit2),其中Form2是登陆窗体,Form1是主窗体。在Form1中我用了 Use unit2 。在Form2中有一个变量IP(String),我在Form1中直接引用了Form2.IP,因为Form2是登陆窗体,在工程代码中,登陆后就给Form2.Free了,不知道和这个有关系吗??
      

  6.   

    当然有关系!但如果是这种情况,应该每次访问IP都会造成AV,而不是偶然出现。
      

  7.   

    IP也被销毁了,程序找不到,就会AV
      

  8.   

    自己还是写的时候注意一些,这个可能有多种原因引起的。编译时不显示错误,运行时有错误肯定是逻辑错误。检测一下出现错误之前的操作,注释掉有可能出现错误的语句,一点一点测试吧。
    检测有无内存泄露可以在窗口创建时加入下面语句
    ReportMemoryLeaksOnShutdown := true;
      

  9.   

    你使用了一个以前被FreeAndNil的对象或其内的成员 
      

  10.   

    偶尔有问题的原因是你访问了一个被Free的对象的成员,但该被Free的对象页还没有被系统回收(以4K为单位进行回收),所以你就走运了。一旦内存页被收回,你再访问,程序就挂了