定义了一个类用来判断编号是否存在,但运行时出错:access violation at address ******** in module 'Project1.exe'.Read of address 00000004.
出错的代码如下:
 function Tbasedata.CheckRec(Id:string):Boolean;
 begin
  Datamod.ADOINF.Close;
  Datamod.ADOINF.SQL.Clear;
  Datamod.ADOINF.SQL.Add(' select * from user_base where worker_id='''+Id+'''');
  Datamod.ADOINF.Open ;
  if Datamod.ADOINF.Eof then result:=false
  else result:=true;
 end;
部分代码:
constructor Tbasedata.create ;
begin
Datamod:=TDM.Create(nil);
end;destructor Tbasedata.Destroy ;
begin
 freeandnil(Datamod);
 inherited;
end; function Tbasedata.GetIdLists():TStrings;
 var
  id:string;
  idrec:TStrings;
 begin
  idrec:=TStringlist.Create ;
  Datamod.ADOINF.Close;
  Datamod.ADOINF.SQL.Clear;
  Datamod.ADOINF.SQL.Add('select * from user_base');
  Datamod.ADOINF.Open;
  while not Datamod.ADOINF.Eof  do
  begin
  id:=Datamod.ADOINF.fieldbyname('worker_id').AsString;
  idrec.Add(Id);
  Datamod.ADOINF.Next;
  end;
  result:=idrec;
 end; function Tbasedata.CheckRec(Id:string):Boolean;
 begin
  Datamod.ADOINF.Close;
  Datamod.ADOINF.SQL.Clear;
  Datamod.ADOINF.SQL.Add(' select * from user_base where worker_id='''+Id+'''');
  Datamod.ADOINF.Open ;
  if Datamod.ADOINF.Eof then result:=false
  else result:=true;
 end;  function Tbasedata.GetArcId(WorkId:string):string;
 begin
  Datamod.ADOINF.Close ;
  Datamod.ADOINF.SQL.Clear;
  Datamod.ADOINF.SQL.Add(' select * from user_base where worker_id='''+WorkId+'''');
  Datamod.ADOINF.Open ;
 result:=Datamod.ADOINF.fieldbyname('archives_id').AsString;
 end;

解决方案 »

  1.   

    Datamod.ADOINF.SQL.Add(' select * from user_base where worker_id='''+WorkId+'''');??????WorkId是从那里来的?从那里得到的呢?上面的也是一样!~
      

  2.   

    Datamod.ADOINF.Close;
      Datamod.ADOINF.SQL.Clear;
      Datamod.ADOINF.SQL.Add(' select * from user_base where worker_id='''+Id+'''');
      Datamod.ADOINF.Open ;
      if Datamod.ADOINF.Eof then result:=false//建议这儿用 if Datamod.ADOINF.isempty ..
      else result:=true;
    destructor Tbasedata.Destroy ;
    begin
     freeandnil(Datamod);
     inherited;//这一句就不用了。前面都把实例释放了,这一句就引起了内存访问错!
    end;
      

  3.   

    出错的代码如下:
     function Tbasedata.CheckRec(Id:string):Boolean;
     begin
      Datamod.ADOINF.Close;
      Datamod.ADOINF.SQL.Clear;
      Datamod.ADOINF.SQL.Add(' select * from user_base where worker_id='''+Id+'''');
      Datamod.ADOINF.Open ;
      if Datamod.ADOINF.Eof then result:=false
      else result:=true;
     end;
    部分代码:
    constructor Tbasedata.create ;
    begin
      Datamod:=TDM.Create(nil);
      //---这个查询组件也要动态创建的。
      adoinf:=tadoquery.create(datamod);
      adoinf.parent:=datamod;
      
    end;Datamod中的ADOINF(adoquery)是动态创建的吗?
    如果是,那在上面的构造方法中,只看到你创建了数据模块TDATAMODAL;没有看到你创建查询组件啊,而你在查询方法中用到了这个组件。呵~~,就是“未创建对象实例,却访问这个对象”引起内存访问错。
    从你的代码来看,只有这个问题会导致内存访问错了。
      

  4.   

    呵~~,上面的代码分析不对。不好意思,自己没有测试。
    你的代码操作是正确的。从你的代码来看,你动态创建的列表 idrec:TStrings;是一个局部的对象,
    这个对象只在你的方法: function Tbasedata.GetIdLists():TStrings;内才有效。
    但你的返回一个列表,也就是返回一个对象指针。
    实际上你的方法:GETIDLISTS()最后一代码:Result:=idrec,只是使你的函数返回值的指针指向了这个局部对象,当这个函数执行完毕后,你所创建的局部对象:idrec就不存在了。
    因为:
        局部对象的生存周期与这个方法的生存财期相同!
        若这个方法完成后返回,则它所拥有的局部变量的内存都将回收!
    当你在后面访问这个列表中的成员时,你所访问的成员地址就是不存在的!可以这样改一下:
     function Tbasedata.GetIdLists():TStrings;
     var
      id:string;
      //idrec:TStrings;这个就可以不需要了。
     begin
      Result:=TStringlist.Create ;
    ......
      

  5.   

    原来是在调用该类的FORM上的FormActivate上少写了一句basedata:=Tbasedata.create;